diff options
author | Edward Fewell | 2017-12-18 20:31:02 -0600 |
---|---|---|
committer | Edward Fewell | 2017-12-18 20:31:02 -0600 |
commit | 497a1fa2969a16d54bc703bd3477e8bb4adb1ef2 (patch) | |
tree | 6104a37f2a4a818102ef649a4eda213d70b34e64 | |
parent | b7a5ff57a44b5c5bb54d4716931185ce6c35420e (diff) | |
download | openocd-497a1fa2969a16d54bc703bd3477e8bb4adb1ef2.tar.gz openocd-497a1fa2969a16d54bc703bd3477e8bb4adb1ef2.tar.xz openocd-497a1fa2969a16d54bc703bd3477e8bb4adb1ef2.zip |
Add support for XDS110 debug probe
-rw-r--r-- | openocd/Makefile.in | 97 | ||||
-rw-r--r-- | openocd/config.h.in | 3 | ||||
-rwxr-xr-x | openocd/configure | 68 | ||||
-rw-r--r-- | openocd/configure.ac | 3 | ||||
-rw-r--r-- | openocd/src/jtag/drivers/Makefile.am | 5 | ||||
-rw-r--r-- | openocd/src/jtag/drivers/xds110.c | 1979 | ||||
-rw-r--r-- | openocd/src/jtag/interfaces.c | 6 | ||||
-rw-r--r-- | openocd/tcl/interface/xds110.cfg | 12 |
8 files changed, 2128 insertions, 45 deletions
diff --git a/openocd/Makefile.in b/openocd/Makefile.in index 5a89a20..b965bbf 100644 --- a/openocd/Makefile.in +++ b/openocd/Makefile.in | |||
@@ -181,12 +181,13 @@ bin_PROGRAMS = src/openocd$(EXEEXT) | |||
181 | @BCM2835GPIO_TRUE@@MINIDRIVER_FALSE@am__append_67 = src/jtag/drivers/bcm2835gpio.c | 181 | @BCM2835GPIO_TRUE@@MINIDRIVER_FALSE@am__append_67 = src/jtag/drivers/bcm2835gpio.c |
182 | @MINIDRIVER_FALSE@@OPENJTAG_TRUE@am__append_68 = src/jtag/drivers/openjtag.c | 182 | @MINIDRIVER_FALSE@@OPENJTAG_TRUE@am__append_68 = src/jtag/drivers/openjtag.c |
183 | @CMSIS_DAP_TRUE@@MINIDRIVER_FALSE@am__append_69 = src/jtag/drivers/cmsis_dap_usb.c | 183 | @CMSIS_DAP_TRUE@@MINIDRIVER_FALSE@am__append_69 = src/jtag/drivers/cmsis_dap_usb.c |
184 | @MINIDRIVER_FALSE@am__append_70 = $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la | 184 | @MINIDRIVER_FALSE@@XDS110_TRUE@am__append_70 = src/jtag/drivers/xds110.c |
185 | @MINIDRIVER_FALSE@am__append_71 = $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la | ||
185 | 186 | ||
186 | # FD_* macros are sloppy with their signs on MinGW32 platform | 187 | # FD_* macros are sloppy with their signs on MinGW32 platform |
187 | @IS_MINGW_TRUE@am__append_71 = -Wno-sign-compare | ||
188 | # FD_* macros are sloppy with their signs on MinGW32 platform | ||
189 | @IS_MINGW_TRUE@am__append_72 = -Wno-sign-compare | 188 | @IS_MINGW_TRUE@am__append_72 = -Wno-sign-compare |
189 | # FD_* macros are sloppy with their signs on MinGW32 platform | ||
190 | @IS_MINGW_TRUE@am__append_73 = -Wno-sign-compare | ||
190 | subdir = . | 191 | subdir = . |
191 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | 192 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
192 | am__aclocal_m4_deps = $(top_srcdir)/config_subdir.m4 \ | 193 | am__aclocal_m4_deps = $(top_srcdir)/config_subdir.m4 \ |
@@ -353,8 +354,8 @@ am__src_jtag_drivers_libocdjtagdrivers_la_SOURCES_DIST = \ | |||
353 | src/jtag/drivers/osbdm.c src/jtag/drivers/opendous.c \ | 354 | src/jtag/drivers/osbdm.c src/jtag/drivers/opendous.c \ |
354 | src/jtag/drivers/sysfsgpio.c src/jtag/drivers/bcm2835gpio.c \ | 355 | src/jtag/drivers/sysfsgpio.c src/jtag/drivers/bcm2835gpio.c \ |
355 | src/jtag/drivers/openjtag.c src/jtag/drivers/cmsis_dap_usb.c \ | 356 | src/jtag/drivers/openjtag.c src/jtag/drivers/cmsis_dap_usb.c \ |
356 | src/jtag/drivers/bitbang.h src/jtag/drivers/bitq.h \ | 357 | src/jtag/drivers/xds110.c src/jtag/drivers/bitbang.h \ |
357 | src/jtag/drivers/libusb0_common.h \ | 358 | src/jtag/drivers/bitq.h src/jtag/drivers/libusb0_common.h \ |
358 | src/jtag/drivers/libusb1_common.h \ | 359 | src/jtag/drivers/libusb1_common.h \ |
359 | src/jtag/drivers/libusb_common.h \ | 360 | src/jtag/drivers/libusb_common.h \ |
360 | src/jtag/drivers/minidriver_imp.h src/jtag/drivers/mpsse.h \ | 361 | src/jtag/drivers/minidriver_imp.h src/jtag/drivers/mpsse.h \ |
@@ -404,7 +405,8 @@ am__src_jtag_drivers_libocdjtagdrivers_la_SOURCES_DIST = \ | |||
404 | @BCM2835GPIO_TRUE@@MINIDRIVER_FALSE@am__objects_32 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-bcm2835gpio.lo | 405 | @BCM2835GPIO_TRUE@@MINIDRIVER_FALSE@am__objects_32 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-bcm2835gpio.lo |
405 | @MINIDRIVER_FALSE@@OPENJTAG_TRUE@am__objects_33 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-openjtag.lo | 406 | @MINIDRIVER_FALSE@@OPENJTAG_TRUE@am__objects_33 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-openjtag.lo |
406 | @CMSIS_DAP_TRUE@@MINIDRIVER_FALSE@am__objects_34 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-cmsis_dap_usb.lo | 407 | @CMSIS_DAP_TRUE@@MINIDRIVER_FALSE@am__objects_34 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-cmsis_dap_usb.lo |
407 | @MINIDRIVER_FALSE@am__objects_35 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-driver.lo \ | 408 | @MINIDRIVER_FALSE@@XDS110_TRUE@am__objects_35 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-xds110.lo |
409 | @MINIDRIVER_FALSE@am__objects_36 = src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-driver.lo \ | ||
408 | @MINIDRIVER_FALSE@ $(am__objects_6) $(am__objects_7) \ | 410 | @MINIDRIVER_FALSE@ $(am__objects_6) $(am__objects_7) \ |
409 | @MINIDRIVER_FALSE@ $(am__objects_8) $(am__objects_9) \ | 411 | @MINIDRIVER_FALSE@ $(am__objects_8) $(am__objects_9) \ |
410 | @MINIDRIVER_FALSE@ $(am__objects_10) $(am__objects_11) \ | 412 | @MINIDRIVER_FALSE@ $(am__objects_10) $(am__objects_11) \ |
@@ -419,9 +421,9 @@ am__src_jtag_drivers_libocdjtagdrivers_la_SOURCES_DIST = \ | |||
419 | @MINIDRIVER_FALSE@ $(am__objects_28) $(am__objects_29) \ | 421 | @MINIDRIVER_FALSE@ $(am__objects_28) $(am__objects_29) \ |
420 | @MINIDRIVER_FALSE@ $(am__objects_30) $(am__objects_31) \ | 422 | @MINIDRIVER_FALSE@ $(am__objects_30) $(am__objects_31) \ |
421 | @MINIDRIVER_FALSE@ $(am__objects_32) $(am__objects_33) \ | 423 | @MINIDRIVER_FALSE@ $(am__objects_32) $(am__objects_33) \ |
422 | @MINIDRIVER_FALSE@ $(am__objects_34) | 424 | @MINIDRIVER_FALSE@ $(am__objects_34) $(am__objects_35) |
423 | @MINIDRIVER_FALSE@am_src_jtag_drivers_libocdjtagdrivers_la_OBJECTS = \ | 425 | @MINIDRIVER_FALSE@am_src_jtag_drivers_libocdjtagdrivers_la_OBJECTS = \ |
424 | @MINIDRIVER_FALSE@ $(am__objects_35) $(am__objects_2) | 426 | @MINIDRIVER_FALSE@ $(am__objects_36) $(am__objects_2) |
425 | src_jtag_drivers_libocdjtagdrivers_la_OBJECTS = \ | 427 | src_jtag_drivers_libocdjtagdrivers_la_OBJECTS = \ |
426 | $(am_src_jtag_drivers_libocdjtagdrivers_la_OBJECTS) | 428 | $(am_src_jtag_drivers_libocdjtagdrivers_la_OBJECTS) |
427 | @MINIDRIVER_FALSE@am_src_jtag_drivers_libocdjtagdrivers_la_rpath = | 429 | @MINIDRIVER_FALSE@am_src_jtag_drivers_libocdjtagdrivers_la_rpath = |
@@ -431,13 +433,13 @@ am__src_jtag_drivers_usb_blaster_libocdusbblaster_la_SOURCES_DIST = \ | |||
431 | src/jtag/drivers/usb_blaster/ublast_access.h \ | 433 | src/jtag/drivers/usb_blaster/ublast_access.h \ |
432 | src/jtag/drivers/usb_blaster/ublast_access_ftdi.c \ | 434 | src/jtag/drivers/usb_blaster/ublast_access_ftdi.c \ |
433 | src/jtag/drivers/usb_blaster/ublast2_access_libusb.c | 435 | src/jtag/drivers/usb_blaster/ublast2_access_libusb.c |
434 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@@USB_BLASTER_TRUE@am__objects_36 = src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-ublast_access_ftdi.lo | 436 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@@USB_BLASTER_TRUE@am__objects_37 = src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-ublast_access_ftdi.lo |
435 | @MINIDRIVER_FALSE@@USB_BLASTER_2_TRUE@@USB_BLASTER_DRIVER_TRUE@am__objects_37 = src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-ublast2_access_libusb.lo | 437 | @MINIDRIVER_FALSE@@USB_BLASTER_2_TRUE@@USB_BLASTER_DRIVER_TRUE@am__objects_38 = src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-ublast2_access_libusb.lo |
436 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@am__objects_38 = src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.lo \ | 438 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@am__objects_39 = src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.lo \ |
437 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@ $(am__objects_36) \ | 439 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@ $(am__objects_37) \ |
438 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@ $(am__objects_37) | ||
439 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@am_src_jtag_drivers_usb_blaster_libocdusbblaster_la_OBJECTS = \ | ||
440 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@ $(am__objects_38) | 440 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@ $(am__objects_38) |
441 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@am_src_jtag_drivers_usb_blaster_libocdusbblaster_la_OBJECTS = \ | ||
442 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@ $(am__objects_39) | ||
441 | src_jtag_drivers_usb_blaster_libocdusbblaster_la_OBJECTS = $(am_src_jtag_drivers_usb_blaster_libocdusbblaster_la_OBJECTS) | 443 | src_jtag_drivers_usb_blaster_libocdusbblaster_la_OBJECTS = $(am_src_jtag_drivers_usb_blaster_libocdusbblaster_la_OBJECTS) |
442 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@am_src_jtag_drivers_usb_blaster_libocdusbblaster_la_rpath = | 444 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@am_src_jtag_drivers_usb_blaster_libocdusbblaster_la_rpath = |
443 | src_jtag_hla_libocdhla_la_LIBADD = | 445 | src_jtag_hla_libocdhla_la_LIBADD = |
@@ -454,7 +456,7 @@ src_jtag_hla_libocdhla_la_OBJECTS = \ | |||
454 | $(am_src_jtag_hla_libocdhla_la_OBJECTS) | 456 | $(am_src_jtag_hla_libocdhla_la_OBJECTS) |
455 | @HLADAPTER_TRUE@@MINIDRIVER_FALSE@am_src_jtag_hla_libocdhla_la_rpath = | 457 | @HLADAPTER_TRUE@@MINIDRIVER_FALSE@am_src_jtag_hla_libocdhla_la_rpath = |
456 | src_jtag_libjtag_la_DEPENDENCIES = $(am__append_17) $(am__append_19) \ | 458 | src_jtag_libjtag_la_DEPENDENCIES = $(am__append_17) $(am__append_19) \ |
457 | $(am__append_70) | 459 | $(am__append_71) |
458 | am__src_jtag_libjtag_la_SOURCES_DIST = src/jtag/adapter.c \ | 460 | am__src_jtag_libjtag_la_SOURCES_DIST = src/jtag/adapter.c \ |
459 | src/jtag/core.c src/jtag/interface.c src/jtag/interfaces.c \ | 461 | src/jtag/core.c src/jtag/interface.c src/jtag/interfaces.c \ |
460 | src/jtag/tcl.c src/jtag/commands.h src/jtag/driver.h \ | 462 | src/jtag/tcl.c src/jtag/commands.h src/jtag/driver.h \ |
@@ -464,15 +466,15 @@ am__src_jtag_libjtag_la_SOURCES_DIST = src/jtag/adapter.c \ | |||
464 | src/jtag/minidummy/jtag_minidriver.h src/jtag/swd.h \ | 466 | src/jtag/minidummy/jtag_minidriver.h src/jtag/swd.h \ |
465 | src/jtag/tcl.h src/jtag/zy1000/zy1000.c \ | 467 | src/jtag/tcl.h src/jtag/zy1000/zy1000.c \ |
466 | src/jtag/minidummy/minidummy.c src/jtag/commands.c | 468 | src/jtag/minidummy/minidummy.c src/jtag/commands.c |
467 | @MINIDRIVER_TRUE@@ZY1000_TRUE@am__objects_39 = \ | 469 | @MINIDRIVER_TRUE@@ZY1000_TRUE@am__objects_40 = \ |
468 | @MINIDRIVER_TRUE@@ZY1000_TRUE@ src/jtag/zy1000/zy1000.lo | 470 | @MINIDRIVER_TRUE@@ZY1000_TRUE@ src/jtag/zy1000/zy1000.lo |
469 | @MINIDRIVER_DUMMY_TRUE@@MINIDRIVER_TRUE@am__objects_40 = src/jtag/minidummy/minidummy.lo \ | 471 | @MINIDRIVER_DUMMY_TRUE@@MINIDRIVER_TRUE@am__objects_41 = src/jtag/minidummy/minidummy.lo \ |
470 | @MINIDRIVER_DUMMY_TRUE@@MINIDRIVER_TRUE@ src/jtag/commands.lo | 472 | @MINIDRIVER_DUMMY_TRUE@@MINIDRIVER_TRUE@ src/jtag/commands.lo |
471 | @MINIDRIVER_FALSE@am__objects_41 = src/jtag/commands.lo | 473 | @MINIDRIVER_FALSE@am__objects_42 = src/jtag/commands.lo |
472 | am__objects_42 = $(am__objects_39) $(am__objects_40) $(am__objects_41) | 474 | am__objects_43 = $(am__objects_40) $(am__objects_41) $(am__objects_42) |
473 | am_src_jtag_libjtag_la_OBJECTS = src/jtag/adapter.lo src/jtag/core.lo \ | 475 | am_src_jtag_libjtag_la_OBJECTS = src/jtag/adapter.lo src/jtag/core.lo \ |
474 | src/jtag/interface.lo src/jtag/interfaces.lo src/jtag/tcl.lo \ | 476 | src/jtag/interface.lo src/jtag/interfaces.lo src/jtag/tcl.lo \ |
475 | $(am__objects_42) | 477 | $(am__objects_43) |
476 | src_jtag_libjtag_la_OBJECTS = $(am_src_jtag_libjtag_la_OBJECTS) | 478 | src_jtag_libjtag_la_OBJECTS = $(am_src_jtag_libjtag_la_OBJECTS) |
477 | src_libopenocd_la_DEPENDENCIES = src/xsvf/libxsvf.la src/svf/libsvf.la \ | 479 | src_libopenocd_la_DEPENDENCIES = src/xsvf/libxsvf.la src/svf/libsvf.la \ |
478 | src/pld/libpld.la src/jtag/libjtag.la \ | 480 | src/pld/libpld.la src/jtag/libjtag.la \ |
@@ -598,47 +600,47 @@ am__src_target_libtarget_la_SOURCES_DIST = src/target/algorithm.c \ | |||
598 | src/target/nds32_v3.h src/target/nds32_v3m.h \ | 600 | src/target/nds32_v3.h src/target/nds32_v3m.h \ |
599 | src/target/nds32_aice.h src/target/lakemont.h \ | 601 | src/target/nds32_aice.h src/target/lakemont.h \ |
600 | src/target/x86_32_common.h | 602 | src/target/x86_32_common.h |
601 | am__objects_43 = src/target/algorithm.lo src/target/register.lo \ | 603 | am__objects_44 = src/target/algorithm.lo src/target/register.lo \ |
602 | src/target/image.lo src/target/breakpoints.lo \ | 604 | src/target/image.lo src/target/breakpoints.lo \ |
603 | src/target/target.lo src/target/target_request.lo \ | 605 | src/target/target.lo src/target/target_request.lo \ |
604 | src/target/testee.lo src/target/smp.lo | 606 | src/target/testee.lo src/target/smp.lo |
605 | @OOCD_TRACE_TRUE@am__objects_44 = src/target/oocd_trace.lo | 607 | @OOCD_TRACE_TRUE@am__objects_45 = src/target/oocd_trace.lo |
606 | am__objects_45 = src/target/arm_dpm.lo src/target/arm_jtag.lo \ | 608 | am__objects_46 = src/target/arm_dpm.lo src/target/arm_jtag.lo \ |
607 | src/target/arm_disassembler.lo src/target/arm_simulator.lo \ | 609 | src/target/arm_disassembler.lo src/target/arm_simulator.lo \ |
608 | src/target/arm_semihosting.lo src/target/arm_adi_v5.lo \ | 610 | src/target/arm_semihosting.lo src/target/arm_adi_v5.lo \ |
609 | src/target/armv7a_cache.lo src/target/armv7a_cache_l2x.lo \ | 611 | src/target/armv7a_cache.lo src/target/armv7a_cache_l2x.lo \ |
610 | src/target/adi_v5_jtag.lo src/target/adi_v5_swd.lo \ | 612 | src/target/adi_v5_jtag.lo src/target/adi_v5_swd.lo \ |
611 | src/target/embeddedice.lo src/target/trace.lo \ | 613 | src/target/embeddedice.lo src/target/trace.lo \ |
612 | src/target/etb.lo src/target/etm.lo $(am__objects_44) \ | 614 | src/target/etb.lo src/target/etm.lo $(am__objects_45) \ |
613 | src/target/etm_dummy.lo | 615 | src/target/etm_dummy.lo |
614 | am__objects_46 = src/target/arm7_9_common.lo src/target/arm7tdmi.lo \ | 616 | am__objects_47 = src/target/arm7_9_common.lo src/target/arm7tdmi.lo \ |
615 | src/target/arm720t.lo src/target/arm9tdmi.lo \ | 617 | src/target/arm720t.lo src/target/arm9tdmi.lo \ |
616 | src/target/arm920t.lo src/target/arm966e.lo \ | 618 | src/target/arm920t.lo src/target/arm966e.lo \ |
617 | src/target/arm946e.lo src/target/arm926ejs.lo \ | 619 | src/target/arm946e.lo src/target/arm926ejs.lo \ |
618 | src/target/feroceon.lo | 620 | src/target/feroceon.lo |
619 | am__objects_47 = src/target/armv4_5.lo src/target/armv4_5_mmu.lo \ | 621 | am__objects_48 = src/target/armv4_5.lo src/target/armv4_5_mmu.lo \ |
620 | src/target/armv4_5_cache.lo $(am__objects_46) | 622 | src/target/armv4_5_cache.lo $(am__objects_47) |
621 | am__objects_48 = src/target/arm11.lo src/target/arm11_dbgtap.lo | 623 | am__objects_49 = src/target/arm11.lo src/target/arm11_dbgtap.lo |
622 | am__objects_49 = src/target/armv7m.lo src/target/armv7m_trace.lo \ | 624 | am__objects_50 = src/target/armv7m.lo src/target/armv7m_trace.lo \ |
623 | src/target/cortex_m.lo src/target/armv7a.lo \ | 625 | src/target/cortex_m.lo src/target/armv7a.lo \ |
624 | src/target/cortex_a.lo src/target/ls1_sap.lo | 626 | src/target/cortex_a.lo src/target/ls1_sap.lo |
625 | am__objects_50 = src/target/fa526.lo src/target/xscale.lo | 627 | am__objects_51 = src/target/fa526.lo src/target/xscale.lo |
626 | am__objects_51 = src/target/avr32_ap7k.lo src/target/avr32_jtag.lo \ | 628 | am__objects_52 = src/target/avr32_ap7k.lo src/target/avr32_jtag.lo \ |
627 | src/target/avr32_mem.lo src/target/avr32_regs.lo | 629 | src/target/avr32_mem.lo src/target/avr32_regs.lo |
628 | am__objects_52 = src/target/mips32.lo src/target/mips_m4k.lo \ | 630 | am__objects_53 = src/target/mips32.lo src/target/mips_m4k.lo \ |
629 | src/target/mips32_pracc.lo src/target/mips32_dmaacc.lo \ | 631 | src/target/mips32_pracc.lo src/target/mips32_dmaacc.lo \ |
630 | src/target/mips_ejtag.lo | 632 | src/target/mips_ejtag.lo |
631 | am__objects_53 = src/target/nds32.lo src/target/nds32_reg.lo \ | 633 | am__objects_54 = src/target/nds32.lo src/target/nds32_reg.lo \ |
632 | src/target/nds32_cmd.lo src/target/nds32_disassembler.lo \ | 634 | src/target/nds32_cmd.lo src/target/nds32_disassembler.lo \ |
633 | src/target/nds32_tlb.lo src/target/nds32_v2.lo \ | 635 | src/target/nds32_tlb.lo src/target/nds32_v2.lo \ |
634 | src/target/nds32_v3_common.lo src/target/nds32_v3.lo \ | 636 | src/target/nds32_v3_common.lo src/target/nds32_v3.lo \ |
635 | src/target/nds32_v3m.lo src/target/nds32_aice.lo | 637 | src/target/nds32_v3m.lo src/target/nds32_aice.lo |
636 | am__objects_54 = src/target/quark_x10xx.lo src/target/quark_d20xx.lo \ | 638 | am__objects_55 = src/target/quark_x10xx.lo src/target/quark_d20xx.lo \ |
637 | src/target/lakemont.lo src/target/x86_32_common.lo | 639 | src/target/lakemont.lo src/target/x86_32_common.lo |
638 | am_src_target_libtarget_la_OBJECTS = $(am__objects_43) \ | 640 | am_src_target_libtarget_la_OBJECTS = $(am__objects_44) \ |
639 | $(am__objects_45) $(am__objects_47) $(am__objects_48) \ | 641 | $(am__objects_46) $(am__objects_48) $(am__objects_49) \ |
640 | $(am__objects_49) $(am__objects_50) $(am__objects_51) \ | 642 | $(am__objects_50) $(am__objects_51) $(am__objects_52) \ |
641 | $(am__objects_52) $(am__objects_53) $(am__objects_54) \ | 643 | $(am__objects_53) $(am__objects_54) $(am__objects_55) \ |
642 | src/target/avrt.lo src/target/dsp563xx.lo \ | 644 | src/target/avrt.lo src/target/dsp563xx.lo \ |
643 | src/target/dsp563xx_once.lo src/target/dsp5680xx.lo \ | 645 | src/target/dsp563xx_once.lo src/target/dsp5680xx.lo \ |
644 | src/target/hla_target.lo | 646 | src/target/hla_target.lo |
@@ -1154,7 +1156,7 @@ src_helper_libhelper_la_SOURCES = src/helper/binarybuffer.c \ | |||
1154 | src_helper_libhelper_la_CFLAGS = $(AM_CFLAGS) $(am__append_10) | 1156 | src_helper_libhelper_la_CFLAGS = $(AM_CFLAGS) $(am__append_10) |
1155 | JTAG_SRCS = $(am__append_11) $(am__append_12) $(am__append_15) | 1157 | JTAG_SRCS = $(am__append_11) $(am__append_12) $(am__append_15) |
1156 | src_jtag_libjtag_la_LIBADD = $(am__append_17) $(am__append_19) \ | 1158 | src_jtag_libjtag_la_LIBADD = $(am__append_17) $(am__append_19) \ |
1157 | $(am__append_70) | 1159 | $(am__append_71) |
1158 | @MINIDRIVER_DUMMY_TRUE@@MINIDRIVER_TRUE@JTAG_MINIDRIVER_DIR = src/jtag/minidummy | 1160 | @MINIDRIVER_DUMMY_TRUE@@MINIDRIVER_TRUE@JTAG_MINIDRIVER_DIR = src/jtag/minidummy |
1159 | @MINIDRIVER_TRUE@@ZY1000_TRUE@JTAG_MINIDRIVER_DIR = src/jtag/zy1000 | 1161 | @MINIDRIVER_TRUE@@ZY1000_TRUE@JTAG_MINIDRIVER_DIR = src/jtag/zy1000 |
1160 | @MINIDRIVER_FALSE@MINIDRIVER_IMP_DIR = src/jtag/drivers | 1162 | @MINIDRIVER_FALSE@MINIDRIVER_IMP_DIR = src/jtag/drivers |
@@ -1214,7 +1216,7 @@ src_jtag_libjtag_la_LIBADD = $(am__append_17) $(am__append_19) \ | |||
1214 | @MINIDRIVER_FALSE@ $(am__append_63) $(am__append_64) \ | 1216 | @MINIDRIVER_FALSE@ $(am__append_63) $(am__append_64) \ |
1215 | @MINIDRIVER_FALSE@ $(am__append_65) $(am__append_66) \ | 1217 | @MINIDRIVER_FALSE@ $(am__append_65) $(am__append_66) \ |
1216 | @MINIDRIVER_FALSE@ $(am__append_67) $(am__append_68) \ | 1218 | @MINIDRIVER_FALSE@ $(am__append_67) $(am__append_68) \ |
1217 | @MINIDRIVER_FALSE@ $(am__append_69) | 1219 | @MINIDRIVER_FALSE@ $(am__append_69) $(am__append_70) |
1218 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@src_jtag_drivers_usb_blaster_libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC) | 1220 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@src_jtag_drivers_usb_blaster_libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC) |
1219 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@src_jtag_drivers_usb_blaster_libocdusbblaster_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS) | 1221 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@src_jtag_drivers_usb_blaster_libocdusbblaster_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS) |
1220 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@USB_BLASTER_SRC = src/jtag/drivers/usb_blaster/usb_blaster.c \ | 1222 | @MINIDRIVER_FALSE@@USB_BLASTER_DRIVER_TRUE@USB_BLASTER_SRC = src/jtag/drivers/usb_blaster/usb_blaster.c \ |
@@ -1437,7 +1439,7 @@ src_rtos_librtos_la_SOURCES = \ | |||
1437 | src/rtos/rtos_mqx_stackings.h \ | 1439 | src/rtos/rtos_mqx_stackings.h \ |
1438 | src/rtos/rtos_ucos_iii_stackings.h | 1440 | src/rtos/rtos_ucos_iii_stackings.h |
1439 | 1441 | ||
1440 | src_rtos_librtos_la_CFLAGS = $(AM_CFLAGS) $(am__append_71) | 1442 | src_rtos_librtos_la_CFLAGS = $(AM_CFLAGS) $(am__append_72) |
1441 | src_server_libserver_la_SOURCES = \ | 1443 | src_server_libserver_la_SOURCES = \ |
1442 | src/server/server.c \ | 1444 | src/server/server.c \ |
1443 | src/server/telnet_server.c \ | 1445 | src/server/telnet_server.c \ |
@@ -1449,7 +1451,7 @@ src_server_libserver_la_SOURCES = \ | |||
1449 | src/server/tcl_server.c \ | 1451 | src/server/tcl_server.c \ |
1450 | src/server/tcl_server.h | 1452 | src/server/tcl_server.h |
1451 | 1453 | ||
1452 | src_server_libserver_la_CFLAGS = $(AM_CFLAGS) $(am__append_72) | 1454 | src_server_libserver_la_CFLAGS = $(AM_CFLAGS) $(am__append_73) |
1453 | src_flash_libflash_la_SOURCES = \ | 1455 | src_flash_libflash_la_SOURCES = \ |
1454 | src/flash/common.c src/flash/common.h \ | 1456 | src/flash/common.c src/flash/common.h \ |
1455 | src/flash/mflash.c src/flash/mflash.h | 1457 | src/flash/mflash.c src/flash/mflash.h |
@@ -2026,6 +2028,9 @@ src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-openjtag.lo: \ | |||
2026 | src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-cmsis_dap_usb.lo: \ | 2028 | src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-cmsis_dap_usb.lo: \ |
2027 | src/jtag/drivers/$(am__dirstamp) \ | 2029 | src/jtag/drivers/$(am__dirstamp) \ |
2028 | src/jtag/drivers/$(DEPDIR)/$(am__dirstamp) | 2030 | src/jtag/drivers/$(DEPDIR)/$(am__dirstamp) |
2031 | src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-xds110.lo: \ | ||
2032 | src/jtag/drivers/$(am__dirstamp) \ | ||
2033 | src/jtag/drivers/$(DEPDIR)/$(am__dirstamp) | ||
2029 | 2034 | ||
2030 | src/jtag/drivers/libocdjtagdrivers.la: $(src_jtag_drivers_libocdjtagdrivers_la_OBJECTS) $(src_jtag_drivers_libocdjtagdrivers_la_DEPENDENCIES) $(EXTRA_src_jtag_drivers_libocdjtagdrivers_la_DEPENDENCIES) src/jtag/drivers/$(am__dirstamp) | 2035 | src/jtag/drivers/libocdjtagdrivers.la: $(src_jtag_drivers_libocdjtagdrivers_la_OBJECTS) $(src_jtag_drivers_libocdjtagdrivers_la_DEPENDENCIES) $(EXTRA_src_jtag_drivers_libocdjtagdrivers_la_DEPENDENCIES) src/jtag/drivers/$(am__dirstamp) |
2031 | $(AM_V_CCLD)$(LINK) $(am_src_jtag_drivers_libocdjtagdrivers_la_rpath) $(src_jtag_drivers_libocdjtagdrivers_la_OBJECTS) $(src_jtag_drivers_libocdjtagdrivers_la_LIBADD) $(LIBS) | 2036 | $(AM_V_CCLD)$(LINK) $(am_src_jtag_drivers_libocdjtagdrivers_la_rpath) $(src_jtag_drivers_libocdjtagdrivers_la_OBJECTS) $(src_jtag_drivers_libocdjtagdrivers_la_LIBADD) $(LIBS) |
@@ -2649,6 +2654,7 @@ distclean-compile: | |||
2649 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-usb_common.Plo@am__quote@ | 2654 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-usb_common.Plo@am__quote@ |
2650 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-usbprog.Plo@am__quote@ | 2655 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-usbprog.Plo@am__quote@ |
2651 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-vsllink.Plo@am__quote@ | 2656 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-vsllink.Plo@am__quote@ |
2657 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-xds110.Plo@am__quote@ | ||
2652 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-ublast2_access_libusb.Plo@am__quote@ | 2658 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-ublast2_access_libusb.Plo@am__quote@ |
2653 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-ublast_access_ftdi.Plo@am__quote@ | 2659 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-ublast_access_ftdi.Plo@am__quote@ |
2654 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.Plo@am__quote@ | 2660 | @AMDEP_TRUE@@am__include@ @am__quote@src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.Plo@am__quote@ |
@@ -3201,6 +3207,13 @@ src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-cmsis_dap_usb.lo: src/jta | |||
3201 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | 3207 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
3202 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_jtag_drivers_libocdjtagdrivers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-cmsis_dap_usb.lo `test -f 'src/jtag/drivers/cmsis_dap_usb.c' || echo '$(srcdir)/'`src/jtag/drivers/cmsis_dap_usb.c | 3208 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_jtag_drivers_libocdjtagdrivers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-cmsis_dap_usb.lo `test -f 'src/jtag/drivers/cmsis_dap_usb.c' || echo '$(srcdir)/'`src/jtag/drivers/cmsis_dap_usb.c |
3203 | 3209 | ||
3210 | src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-xds110.lo: src/jtag/drivers/xds110.c | ||
3211 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_jtag_drivers_libocdjtagdrivers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-xds110.lo -MD -MP -MF src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-xds110.Tpo -c -o src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-xds110.lo `test -f 'src/jtag/drivers/xds110.c' || echo '$(srcdir)/'`src/jtag/drivers/xds110.c | ||
3212 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-xds110.Tpo src/jtag/drivers/$(DEPDIR)/src_jtag_drivers_libocdjtagdrivers_la-xds110.Plo | ||
3213 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/jtag/drivers/xds110.c' object='src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-xds110.lo' libtool=yes @AMDEPBACKSLASH@ | ||
3214 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
3215 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_jtag_drivers_libocdjtagdrivers_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/jtag/drivers/src_jtag_drivers_libocdjtagdrivers_la-xds110.lo `test -f 'src/jtag/drivers/xds110.c' || echo '$(srcdir)/'`src/jtag/drivers/xds110.c | ||
3216 | |||
3204 | src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.lo: src/jtag/drivers/usb_blaster/usb_blaster.c | 3217 | src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.lo: src/jtag/drivers/usb_blaster/usb_blaster.c |
3205 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_jtag_drivers_usb_blaster_libocdusbblaster_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.lo -MD -MP -MF src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.Tpo -c -o src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.lo `test -f 'src/jtag/drivers/usb_blaster/usb_blaster.c' || echo '$(srcdir)/'`src/jtag/drivers/usb_blaster/usb_blaster.c | 3218 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_jtag_drivers_usb_blaster_libocdusbblaster_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.lo -MD -MP -MF src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.Tpo -c -o src/jtag/drivers/usb_blaster/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.lo `test -f 'src/jtag/drivers/usb_blaster/usb_blaster.c' || echo '$(srcdir)/'`src/jtag/drivers/usb_blaster/usb_blaster.c |
3206 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.Tpo src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.Plo | 3219 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.Tpo src/jtag/drivers/usb_blaster/$(DEPDIR)/src_jtag_drivers_usb_blaster_libocdusbblaster_la-usb_blaster.Plo |
diff --git a/openocd/config.h.in b/openocd/config.h.in index dded45e..0ca7dbc 100644 --- a/openocd/config.h.in +++ b/openocd/config.h.in | |||
@@ -96,6 +96,9 @@ | |||
96 | /* 0 if you do not want the Versaloon-Link JTAG Programmer. */ | 96 | /* 0 if you do not want the Versaloon-Link JTAG Programmer. */ |
97 | #undef BUILD_VSLLINK | 97 | #undef BUILD_VSLLINK |
98 | 98 | ||
99 | /* 0 if you do not want the TI XDS110 Debug Probe. */ | ||
100 | #undef BUILD_XDS110 | ||
101 | |||
99 | /* 0 if you don't want ZY1000. */ | 102 | /* 0 if you don't want ZY1000. */ |
100 | #undef BUILD_ZY1000 | 103 | #undef BUILD_ZY1000 |
101 | 104 | ||
diff --git a/openocd/configure b/openocd/configure index 974c119..16f7068 100755 --- a/openocd/configure +++ b/openocd/configure | |||
@@ -728,6 +728,8 @@ OPENDOUS_FALSE | |||
728 | OPENDOUS_TRUE | 728 | OPENDOUS_TRUE |
729 | OSBDM_FALSE | 729 | OSBDM_FALSE |
730 | OSBDM_TRUE | 730 | OSBDM_TRUE |
731 | XDS110_FALSE | ||
732 | XDS110_TRUE | ||
731 | VSLLINK_FALSE | 733 | VSLLINK_FALSE |
732 | VSLLINK_TRUE | 734 | VSLLINK_TRUE |
733 | USB_BLASTER_2_FALSE | 735 | USB_BLASTER_2_FALSE |
@@ -903,6 +905,7 @@ enable_ti_icdi | |||
903 | enable_ulink | 905 | enable_ulink |
904 | enable_usb_blaster_2 | 906 | enable_usb_blaster_2 |
905 | enable_vsllink | 907 | enable_vsllink |
908 | enable_xds110 | ||
906 | enable_osbdm | 909 | enable_osbdm |
907 | enable_opendous | 910 | enable_opendous |
908 | enable_aice | 911 | enable_aice |
@@ -1626,6 +1629,8 @@ Optional Features: | |||
1626 | II Compatible (default is auto) | 1629 | II Compatible (default is auto) |
1627 | --enable-vsllink Enable building support for the Versaloon-Link JTAG | 1630 | --enable-vsllink Enable building support for the Versaloon-Link JTAG |
1628 | Programmer (default is auto) | 1631 | Programmer (default is auto) |
1632 | --enable-xds110 Enable building support for the TI XDS110 Debug | ||
1633 | Probe (default is auto) | ||
1629 | --enable-osbdm Enable building support for the OSBDM (JTAG only) | 1634 | --enable-osbdm Enable building support for the OSBDM (JTAG only) |
1630 | Programmer (default is auto) | 1635 | Programmer (default is auto) |
1631 | --enable-opendous Enable building support for the eStick/opendous JTAG | 1636 | --enable-opendous Enable building support for the eStick/opendous JTAG |
@@ -13968,6 +13973,13 @@ else | |||
13968 | enable_vsllink=auto | 13973 | enable_vsllink=auto |
13969 | fi | 13974 | fi |
13970 | 13975 | ||
13976 | # Check whether --enable-xds110 was given. | ||
13977 | if test "${enable_xds110+set}" = set; then : | ||
13978 | enableval=$enable_xds110; | ||
13979 | else | ||
13980 | enable_xds110=auto | ||
13981 | fi | ||
13982 | |||
13971 | # Check whether --enable-osbdm was given. | 13983 | # Check whether --enable-osbdm was given. |
13972 | if test "${enable_osbdm+set}" = set; then : | 13984 | if test "${enable_osbdm+set}" = set; then : |
13973 | enableval=$enable_osbdm; | 13985 | enableval=$enable_osbdm; |
@@ -15477,6 +15489,41 @@ else | |||
15477 | fi | 15489 | fi |
15478 | 15490 | ||
15479 | 15491 | ||
15492 | if test "x$use_libusb1" = "xyes"; then : | ||
15493 | |||
15494 | if test "x$enable_xds110" != "xno"; then : | ||
15495 | |||
15496 | |||
15497 | $as_echo "#define BUILD_XDS110 1" >>confdefs.h | ||
15498 | |||
15499 | |||
15500 | else | ||
15501 | |||
15502 | |||
15503 | $as_echo "#define BUILD_XDS110 0" >>confdefs.h | ||
15504 | |||
15505 | |||
15506 | fi | ||
15507 | |||
15508 | else | ||
15509 | |||
15510 | if test "x$enable_xds110" = "xyes"; then : | ||
15511 | |||
15512 | as_fn_error $? "libusb-1.x is required for the TI XDS110 Debug Probe" "$LINENO" 5 | ||
15513 | |||
15514 | fi | ||
15515 | enable_xds110=no | ||
15516 | |||
15517 | fi | ||
15518 | if test "x$enable_xds110" != "xno"; then | ||
15519 | XDS110_TRUE= | ||
15520 | XDS110_FALSE='#' | ||
15521 | else | ||
15522 | XDS110_TRUE='#' | ||
15523 | XDS110_FALSE= | ||
15524 | fi | ||
15525 | |||
15526 | |||
15480 | 15527 | ||
15481 | 15528 | ||
15482 | 15529 | ||
@@ -16474,6 +16521,10 @@ if test -z "${VSLLINK_TRUE}" && test -z "${VSLLINK_FALSE}"; then | |||
16474 | as_fn_error $? "conditional \"VSLLINK\" was never defined. | 16521 | as_fn_error $? "conditional \"VSLLINK\" was never defined. |
16475 | Usually this means the macro was only invoked conditionally." "$LINENO" 5 | 16522 | Usually this means the macro was only invoked conditionally." "$LINENO" 5 |
16476 | fi | 16523 | fi |
16524 | if test -z "${XDS110_TRUE}" && test -z "${XDS110_FALSE}"; then | ||
16525 | as_fn_error $? "conditional \"XDS110\" was never defined. | ||
16526 | Usually this means the macro was only invoked conditionally." "$LINENO" 5 | ||
16527 | fi | ||
16477 | if test -z "${OSBDM_TRUE}" && test -z "${OSBDM_FALSE}"; then | 16528 | if test -z "${OSBDM_TRUE}" && test -z "${OSBDM_FALSE}"; then |
16478 | as_fn_error $? "conditional \"OSBDM\" was never defined. | 16529 | as_fn_error $? "conditional \"OSBDM\" was never defined. |
16479 | Usually this means the macro was only invoked conditionally." "$LINENO" 5 | 16530 | Usually this means the macro was only invoked conditionally." "$LINENO" 5 |
@@ -19054,6 +19105,23 @@ s="Versaloon-Link JTAG Programmer " | |||
19054 | *) : | 19105 | *) : |
19055 | ;; | 19106 | ;; |
19056 | esac | 19107 | esac |
19108 | s="TI XDS110 Debug Probe " | ||
19109 | case $enable_xds110 in #( | ||
19110 | auto) : | ||
19111 | |||
19112 | echo "$s"yes '(auto)' | ||
19113 | ;; #( | ||
19114 | yes) : | ||
19115 | |||
19116 | echo "$s"yes | ||
19117 | ;; #( | ||
19118 | no) : | ||
19119 | |||
19120 | echo "$s"no | ||
19121 | ;; #( | ||
19122 | *) : | ||
19123 | ;; | ||
19124 | esac | ||
19057 | s="OSBDM (JTAG only) Programmer " | 19125 | s="OSBDM (JTAG only) Programmer " |
19058 | case $enable_osbdm in #( | 19126 | case $enable_osbdm in #( |
19059 | auto) : | 19127 | auto) : |
diff --git a/openocd/configure.ac b/openocd/configure.ac index 6949402..62c0cf5 100644 --- a/openocd/configure.ac +++ b/openocd/configure.ac | |||
@@ -114,7 +114,8 @@ m4_define([USB1_ADAPTERS], | |||
114 | [[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]], | 114 | [[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]], |
115 | [[ulink], [Keil ULINK JTAG Programmer], [ULINK]], | 115 | [[ulink], [Keil ULINK JTAG Programmer], [ULINK]], |
116 | [[usb_blaster_2], [Altera USB-Blaster II Compatible], [USB_BLASTER_2]], | 116 | [[usb_blaster_2], [Altera USB-Blaster II Compatible], [USB_BLASTER_2]], |
117 | [[vsllink], [Versaloon-Link JTAG Programmer], [VSLLINK]]]) | 117 | [[vsllink], [Versaloon-Link JTAG Programmer], [VSLLINK]], |
118 | [[xds110], [TI XDS110 Debug Probe], [XDS110]]]) | ||
118 | 119 | ||
119 | m4_define([USB_ADAPTERS], | 120 | m4_define([USB_ADAPTERS], |
120 | [[[osbdm], [OSBDM (JTAG only) Programmer], [OSBDM]], | 121 | [[[osbdm], [OSBDM (JTAG only) Programmer], [OSBDM]], |
diff --git a/openocd/src/jtag/drivers/Makefile.am b/openocd/src/jtag/drivers/Makefile.am index e411412..823e029 100644 --- a/openocd/src/jtag/drivers/Makefile.am +++ b/openocd/src/jtag/drivers/Makefile.am | |||
@@ -144,14 +144,15 @@ endif | |||
144 | if BCM2835GPIO | 144 | if BCM2835GPIO |
145 | DRIVERFILES += %D%/bcm2835gpio.c | 145 | DRIVERFILES += %D%/bcm2835gpio.c |
146 | endif | 146 | endif |
147 | |||
148 | if OPENJTAG | 147 | if OPENJTAG |
149 | DRIVERFILES += %D%/openjtag.c | 148 | DRIVERFILES += %D%/openjtag.c |
150 | endif | 149 | endif |
151 | |||
152 | if CMSIS_DAP | 150 | if CMSIS_DAP |
153 | DRIVERFILES += %D%/cmsis_dap_usb.c | 151 | DRIVERFILES += %D%/cmsis_dap_usb.c |
154 | endif | 152 | endif |
153 | if XDS110 | ||
154 | DRIVERFILES += %D%/xds110.c | ||
155 | endif | ||
155 | 156 | ||
156 | DRIVERHEADERS = \ | 157 | DRIVERHEADERS = \ |
157 | %D%/bitbang.h \ | 158 | %D%/bitbang.h \ |
diff --git a/openocd/src/jtag/drivers/xds110.c b/openocd/src/jtag/drivers/xds110.c new file mode 100644 index 0000000..5e1a7bf --- /dev/null +++ b/openocd/src/jtag/drivers/xds110.c | |||
@@ -0,0 +1,1979 @@ | |||
1 | /*************************************************************************** | ||
2 | * Copyright (C) 2017 by Texas Instruments, Inc. * | ||
3 | * * | ||
4 | * This program is free software; you can redistribute it and/or modify * | ||
5 | * it under the terms of the GNU General Public License as published by * | ||
6 | * the Free Software Foundation; either version 2 of the License, or * | ||
7 | * (at your option) any later version. * | ||
8 | * * | ||
9 | * This program is distributed in the hope that it will be useful, * | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
12 | * GNU General Public License for more details. * | ||
13 | * * | ||
14 | * You should have received a copy of the GNU General Public License * | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
16 | ***************************************************************************/ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | #include "config.h" | ||
20 | #endif | ||
21 | |||
22 | #include <transport/transport.h> | ||
23 | #include <jtag/swd.h> | ||
24 | #include <jtag/interface.h> | ||
25 | #include <jtag/commands.h> | ||
26 | #include <jtag/tcl.h> | ||
27 | #include <libusb.h> | ||
28 | |||
29 | #if defined(__APPLE_CC__) | ||
30 | #pragma GCC diagnostic ignored "-Wcast-align" | ||
31 | #endif | ||
32 | |||
33 | /* XDS110 USB serial number length */ | ||
34 | #define XDS110_SERIAL_LEN 8 | ||
35 | |||
36 | /* Firmware version that introduced OpenOCD support via block accesses */ | ||
37 | #define OCD_FIRMWARE_VERSION 0x02030011 | ||
38 | #define OCD_FIRMWARE_UPGRADE \ | ||
39 | "XDS110: upgrade to version 2.3.0.11+ for improved support" | ||
40 | |||
41 | /*************************************************************************** | ||
42 | * USB Connection Buffer Definitions * | ||
43 | ***************************************************************************/ | ||
44 | |||
45 | /* Max USB packet size for up to USB 3.0 */ | ||
46 | #define MAX_PACKET 1024 | ||
47 | |||
48 | /* | ||
49 | * Maximum data payload that can be handled in a single call | ||
50 | * Limitation is the size of the buffers in the XDS110 firmware | ||
51 | */ | ||
52 | #define MAX_DATA_BLOCK 4096 | ||
53 | |||
54 | #ifndef USB_PAYLOAD_SIZE | ||
55 | /* Largest data block plus parameters */ | ||
56 | #define USB_PAYLOAD_SIZE (MAX_DATA_BLOCK + 60) | ||
57 | #endif | ||
58 | #define MAX_RESULT_QUEUE (MAX_DATA_BLOCK / 4) | ||
59 | |||
60 | /*************************************************************************** | ||
61 | * USB Connection Endpoints * | ||
62 | ***************************************************************************/ | ||
63 | |||
64 | /* Bulk endpoints used by the XDS110 debug interface */ | ||
65 | #define INTERFACE_DEBUG (2) | ||
66 | #define ENDPOINT_DEBUG_IN (3 | LIBUSB_ENDPOINT_IN) | ||
67 | #define ENDPOINT_DEBUG_OUT (2 | LIBUSB_ENDPOINT_OUT) | ||
68 | |||
69 | /*************************************************************************** | ||
70 | * XDS110 Firmware API Definitions * | ||
71 | ***************************************************************************/ | ||
72 | |||
73 | /* | ||
74 | * Default values controlling how the host communicates commands | ||
75 | * with XDS110 firmware (automatic retry count and wait timeout) | ||
76 | */ | ||
77 | #define DEFAULT_ATTEMPTS (1) | ||
78 | #define DEFAULT_TIMEOUT (4000) | ||
79 | |||
80 | /* Error codes */ | ||
81 | #define SC_ERR_NONE 0 | ||
82 | #define SC_ERR_XDS110_FAIL -261 | ||
83 | #define SC_ERR_SWD_WAIT -613 | ||
84 | #define SC_ERR_SWD_FAULT -614 | ||
85 | #define SC_ERR_SWD_PROTOCOL -615 | ||
86 | #define SC_ERR_SWD_PARITY -616 | ||
87 | #define SC_ERR_SWD_DEVICE_ID -617 | ||
88 | |||
89 | /* TCK frequency limits */ | ||
90 | #define XDS110_MIN_TCK_SPEED 100 /* kHz */ | ||
91 | #define XDS110_MAX_TCK_SPEED 2500 /* kHz */ | ||
92 | #define XDS110_TCK_PULSE_INCREMENT 66.0 | ||
93 | |||
94 | /* Scan mode on connect */ | ||
95 | #define MODE_JTAG 1 | ||
96 | |||
97 | /* XDS110 API JTAG state definitions */ | ||
98 | #define XDS_JTAG_STATE_RESET 1 | ||
99 | #define XDS_JTAG_STATE_IDLE 2 | ||
100 | #define XDS_JTAG_STATE_SHIFT_DR 3 | ||
101 | #define XDS_JTAG_STATE_SHIFT_IR 4 | ||
102 | #define XDS_JTAG_STATE_PAUSE_DR 5 | ||
103 | #define XDS_JTAG_STATE_PAUSE_IR 6 | ||
104 | #define XDS_JTAG_STATE_EXIT1_DR 8 | ||
105 | #define XDS_JTAG_STATE_EXIT1_IR 9 | ||
106 | #define XDS_JTAG_STATE_EXIT2_DR 10 | ||
107 | #define XDS_JTAG_STATE_EXIT2_IR 11 | ||
108 | #define XDS_JTAG_STATE_SELECT_DR 12 | ||
109 | #define XDS_JTAG_STATE_SELECT_IR 13 | ||
110 | #define XDS_JTAG_STATE_UPDATE_DR 14 | ||
111 | #define XDS_JTAG_STATE_UPDATE_IR 15 | ||
112 | #define XDS_JTAG_STATE_CAPTURE_DR 16 | ||
113 | #define XDS_JTAG_STATE_CAPTURE_IR 17 | ||
114 | |||
115 | /* XDS110 API JTAG transit definitions */ | ||
116 | #define XDS_JTAG_TRANSIT_QUICKEST 1 | ||
117 | #define XDS_JTAG_TRANSIT_VIA_CAPTURE 2 | ||
118 | #define XDS_JTAG_TRANSIT_VIA_IDLE 3 | ||
119 | |||
120 | /* DAP register definitions as used by XDS110 APIs */ | ||
121 | |||
122 | #define DAP_AP 0 /* DAP AP register type */ | ||
123 | #define DAP_DP 1 /* DAP DP register type */ | ||
124 | |||
125 | #define DAP_DP_IDCODE 0x0 /* DAP DP IDCODE register (read only) */ | ||
126 | #define DAP_DP_ABORT 0x0 /* DAP DP ABORT register (write only) */ | ||
127 | #define DAP_DP_STAT 0x4 /* DAP DP STAT register (for read only) */ | ||
128 | #define DAP_DP_CTRL 0x4 /* DAP DP CTRL register (for write only) */ | ||
129 | #define DAP_DP_ADDR 0x8 /* DAP DP SELECT register (legacy name) */ | ||
130 | #define DAP_DP_RESEND 0x8 /* DAP DP RESEND register (read only) */ | ||
131 | #define DAP_DP_SELECT 0x8 /* DAP DP SELECT register (write only) */ | ||
132 | #define DAP_DP_RDBUFF 0xc /* DAP DP RDBUFF Read Buffer register */ | ||
133 | |||
134 | #define DAP_AP_CSW 0x00 /* DAP AP Control Status Word */ | ||
135 | #define DAP_AP_TAR 0x04 /* DAP AP Transfer Address */ | ||
136 | #define DAP_AP_DRW 0x0C /* DAP AP Data Read/Write */ | ||
137 | #define DAP_AP_BD0 0x10 /* DAP AP Banked Data 0 */ | ||
138 | #define DAP_AP_BD1 0x14 /* DAP AP Banked Data 1 */ | ||
139 | #define DAP_AP_BD2 0x18 /* DAP AP Banked Data 2 */ | ||
140 | #define DAP_AP_BD3 0x1C /* DAP AP Banked Data 3 */ | ||
141 | #define DAP_AP_RTBL 0xF8 /* DAP AP Debug ROM Table */ | ||
142 | #define DAP_AP_IDR 0xFC /* DAP AP Identification Register */ | ||
143 | |||
144 | /* Command packet definitions */ | ||
145 | |||
146 | #define XDS_OUT_LEN 1 /* command (byte) */ | ||
147 | #define XDS_IN_LEN 4 /* error code (int) */ | ||
148 | |||
149 | /* XDS Commands */ | ||
150 | #define XDS_CONNECT 0x01 /* Connect JTAG connection */ | ||
151 | #define XDS_DISCONNECT 0x02 /* Disconnect JTAG connection */ | ||
152 | #define XDS_VERSION 0x03 /* Get firmware version and hardware ID */ | ||
153 | #define XDS_SET_TCK 0x04 /* Set TCK delay (to set TCK frequency) */ | ||
154 | #define XDS_SET_TRST 0x05 /* Assert or deassert nTRST signal */ | ||
155 | #define XDS_CYCLE_TCK 0x07 /* Toggle TCK for a number of cycles */ | ||
156 | #define XDS_GOTO_STATE 0x09 /* Go to requested JTAG state */ | ||
157 | #define XDS_JTAG_SCAN 0x0c /* Send and receive JTAG scan */ | ||
158 | #define XDS_SET_SRST 0x0e /* Assert or deassert nSRST signal */ | ||
159 | #define CMAPI_CONNECT 0x0f /* CMAPI connect */ | ||
160 | #define CMAPI_DISCONNECT 0x10 /* CMAPI disconnect */ | ||
161 | #define CMAPI_ACQUIRE 0x11 /* CMAPI acquire */ | ||
162 | #define CMAPI_RELEASE 0x12 /* CMAPI release */ | ||
163 | #define CMAPI_REG_READ 0x15 /* CMAPI DAP register read */ | ||
164 | #define CMAPI_REG_WRITE 0x16 /* CMAPI DAP register write */ | ||
165 | #define SWD_CONNECT 0x17 /* Switch from JTAG to SWD connection */ | ||
166 | #define SWD_DISCONNECT 0x18 /* Switch from SWD to JTAG connection */ | ||
167 | #define CJTAG_CONNECT 0x2b /* Switch from JTAG to cJTAG connection */ | ||
168 | #define CJTAG_DISCONNECT 0x2c /* Switch from cJTAG to JTAG connection */ | ||
169 | #define OCD_DAP_REQUEST 0x3a /* Handle block of DAP requests */ | ||
170 | #define OCD_SCAN_REQUEST 0x3b /* Handle block of JTAG scan requests */ | ||
171 | #define OCD_PATHMOVE 0x3c /* Handle PATHMOVE to navigate JTAG states */ | ||
172 | |||
173 | #define CMD_IR_SCAN 1 | ||
174 | #define CMD_DR_SCAN 2 | ||
175 | #define CMD_RUNTEST 3 | ||
176 | #define CMD_STABLECLOCKS 4 | ||
177 | |||
178 | /* Array to convert from tap_state_t to XDS JTAG state */ | ||
179 | const uint32_t xds_jtag_state[] = { | ||
180 | XDS_JTAG_STATE_EXIT2_DR, /* TAP_DREXIT2 = 0x0 */ | ||
181 | XDS_JTAG_STATE_EXIT1_DR, /* TAP_DREXIT1 = 0x1 */ | ||
182 | XDS_JTAG_STATE_SHIFT_DR, /* TAP_DRSHIFT = 0x2 */ | ||
183 | XDS_JTAG_STATE_PAUSE_DR, /* TAP_DRPAUSE = 0x3 */ | ||
184 | XDS_JTAG_STATE_SELECT_IR, /* TAP_IRSELECT = 0x4 */ | ||
185 | XDS_JTAG_STATE_UPDATE_DR, /* TAP_DRUPDATE = 0x5 */ | ||
186 | XDS_JTAG_STATE_CAPTURE_DR, /* TAP_DRCAPTURE = 0x6 */ | ||
187 | XDS_JTAG_STATE_SELECT_DR, /* TAP_DRSELECT = 0x7 */ | ||
188 | XDS_JTAG_STATE_EXIT2_IR, /* TAP_IREXIT2 = 0x8 */ | ||
189 | XDS_JTAG_STATE_EXIT1_IR, /* TAP_IREXIT1 = 0x9 */ | ||
190 | XDS_JTAG_STATE_SHIFT_IR, /* TAP_IRSHIFT = 0xa */ | ||
191 | XDS_JTAG_STATE_PAUSE_IR, /* TAP_IRPAUSE = 0xb */ | ||
192 | XDS_JTAG_STATE_IDLE, /* TAP_IDLE = 0xc */ | ||
193 | XDS_JTAG_STATE_UPDATE_IR, /* TAP_IRUPDATE = 0xd */ | ||
194 | XDS_JTAG_STATE_CAPTURE_IR, /* TAP_IRCAPTURE = 0xe */ | ||
195 | XDS_JTAG_STATE_RESET, /* TAP_RESET = 0xf */ | ||
196 | }; | ||
197 | |||
198 | struct scan_result { | ||
199 | bool first; | ||
200 | uint8_t *buffer; | ||
201 | uint32_t num_bits; | ||
202 | }; | ||
203 | |||
204 | struct xds110_info { | ||
205 | /* USB connection handles and data buffers */ | ||
206 | libusb_context *ctx; | ||
207 | libusb_device_handle *dev; | ||
208 | unsigned char read_payload[USB_PAYLOAD_SIZE]; | ||
209 | unsigned char write_packet[3]; | ||
210 | unsigned char write_payload[USB_PAYLOAD_SIZE]; | ||
211 | /* Status flags */ | ||
212 | bool is_connected; | ||
213 | bool is_cmapi_connected; | ||
214 | bool is_cmapi_acquired; | ||
215 | bool is_swd_mode; | ||
216 | bool is_ap_dirty; | ||
217 | /* DAP register caches */ | ||
218 | uint32_t select; | ||
219 | uint32_t rdbuff; | ||
220 | bool use_rdbuff; | ||
221 | /* TCK speed and delay count*/ | ||
222 | uint32_t speed; | ||
223 | uint32_t delay_count; | ||
224 | /* XDS110 serial number */ | ||
225 | char serial[XDS110_SERIAL_LEN + 1]; | ||
226 | /* XDS110 firmware and hardware version */ | ||
227 | uint32_t firmware; | ||
228 | uint16_t hardware; | ||
229 | /* Transaction queues */ | ||
230 | unsigned char txn_requests[MAX_DATA_BLOCK]; | ||
231 | uint32_t *txn_dap_results[MAX_DATA_BLOCK / 4]; | ||
232 | struct scan_result txn_scan_results[MAX_DATA_BLOCK / 4]; | ||
233 | uint32_t txn_request_size; | ||
234 | uint32_t txn_result_size; | ||
235 | uint32_t txn_result_count; | ||
236 | }; | ||
237 | |||
238 | static struct xds110_info xds110 = { | ||
239 | .ctx = 0, | ||
240 | .dev = 0, | ||
241 | .is_connected = false, | ||
242 | .is_cmapi_connected = false, | ||
243 | .is_cmapi_acquired = false, | ||
244 | .is_swd_mode = false, | ||
245 | .is_ap_dirty = false, | ||
246 | .speed = XDS110_MAX_TCK_SPEED, | ||
247 | .delay_count = 0, | ||
248 | .serial = {0}, | ||
249 | .firmware = 0, | ||
250 | .hardware = 0, | ||
251 | .txn_request_size = 0, | ||
252 | .txn_result_size = 0, | ||
253 | .txn_result_count = 0 | ||
254 | }; | ||
255 | |||
256 | /*************************************************************************** | ||
257 | * usb connection routines * | ||
258 | * * | ||
259 | * The following functions handle connecting, reading, and writing to * | ||
260 | * the XDS110 over USB using the libusb library. * | ||
261 | ***************************************************************************/ | ||
262 | |||
263 | static bool usb_connect(void) | ||
264 | { | ||
265 | libusb_context *ctx = 0; | ||
266 | libusb_device **list = 0; | ||
267 | libusb_device_handle *dev = 0; | ||
268 | |||
269 | struct libusb_device_descriptor desc; | ||
270 | |||
271 | uint16_t vid = 0x0451; | ||
272 | uint16_t pid = 0xbef3; | ||
273 | ssize_t count = 0; | ||
274 | ssize_t i = 0; | ||
275 | int result = 0; | ||
276 | bool found = false; | ||
277 | |||
278 | /* Initialize libusb context */ | ||
279 | result = libusb_init(&ctx); | ||
280 | |||
281 | if (0 == result) { | ||
282 | /* Get list of USB devices attached to system */ | ||
283 | count = libusb_get_device_list(ctx, &list); | ||
284 | if (count <= 0) { | ||
285 | result = -1; | ||
286 | list = 0; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | if (0 == result) { | ||
291 | /* Scan through list of devices for any XDS110s */ | ||
292 | for (i = 0; i < count; i++) { | ||
293 | /* Check for device VID/PID match */ | ||
294 | libusb_get_device_descriptor(list[i], &desc); | ||
295 | if (desc.idVendor == vid && desc.idProduct == pid) { | ||
296 | result = libusb_open(list[i], &dev); | ||
297 | if (0 == result) { | ||
298 | const int MAX_DATA = 256; | ||
299 | unsigned char data[MAX_DATA + 1]; | ||
300 | *data = '\0'; | ||
301 | |||
302 | /* May be the requested device if serial number matches */ | ||
303 | if (0 == xds110.serial[0]) { | ||
304 | /* No serial number given; match first XDS110 found */ | ||
305 | found = true; | ||
306 | break; | ||
307 | } else { | ||
308 | /* Get the device's serial number string */ | ||
309 | result = libusb_get_string_descriptor_ascii(dev, | ||
310 | desc.iSerialNumber, data, MAX_DATA); | ||
311 | if (0 < result && | ||
312 | 0 == strcmp((char *)data, (char *)xds110.serial)) { | ||
313 | found = true; | ||
314 | break; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | /* If we fall though to here, we don't want this device */ | ||
319 | libusb_close(dev); | ||
320 | dev = 0; | ||
321 | } | ||
322 | } | ||
323 | } | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * We can fall through the for() loop with two possible exit conditions: | ||
328 | * 1) found the right XDS110, and that device is open | ||
329 | * 2) didn't find the XDS110, and no devices are currently open | ||
330 | */ | ||
331 | |||
332 | if (0 != list) { | ||
333 | /* Free the device list, we're done with it */ | ||
334 | libusb_free_device_list(list, 1); | ||
335 | } | ||
336 | |||
337 | if (found) { | ||
338 | /* Save the context and device handles */ | ||
339 | xds110.ctx = ctx; | ||
340 | xds110.dev = dev; | ||
341 | |||
342 | /* Set libusb to auto detach kernel and disable debug messages */ | ||
343 | (void)libusb_set_auto_detach_kernel_driver(dev, 1); | ||
344 | libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_NONE); | ||
345 | |||
346 | /* Claim the debug interface on the XDS110 */ | ||
347 | result = libusb_claim_interface(dev, INTERFACE_DEBUG); | ||
348 | } else { | ||
349 | /* Couldn't find an XDS110, flag the error */ | ||
350 | result = -1; | ||
351 | } | ||
352 | |||
353 | /* On an error, clean up what we can */ | ||
354 | if (0 != result) { | ||
355 | if (0 != dev) { | ||
356 | /* Release the debug and data interface on the XDS110 */ | ||
357 | (void)libusb_release_interface(dev, INTERFACE_DEBUG); | ||
358 | libusb_close(dev); | ||
359 | dev = 0; | ||
360 | } | ||
361 | if (0 != ctx) { | ||
362 | libusb_exit(ctx); | ||
363 | ctx = 0; | ||
364 | } | ||
365 | xds110.ctx = 0; | ||
366 | xds110.dev = 0; | ||
367 | } | ||
368 | |||
369 | /* Log the results */ | ||
370 | if (0 == result) | ||
371 | LOG_INFO("XDS110: connected"); | ||
372 | else | ||
373 | LOG_ERROR("XDS110: failed to connect"); | ||
374 | |||
375 | return (0 == result) ? true : false; | ||
376 | } | ||
377 | |||
378 | static void usb_disconnect(void) | ||
379 | { | ||
380 | if (0 != xds110.dev) { | ||
381 | /* Release the debug and data interface on the XDS110 */ | ||
382 | (void)libusb_release_interface(xds110.dev, INTERFACE_DEBUG); | ||
383 | libusb_close(xds110.dev); | ||
384 | xds110.dev = 0; | ||
385 | } | ||
386 | if (0 != xds110.ctx) { | ||
387 | libusb_exit(xds110.ctx); | ||
388 | xds110.ctx = 0; | ||
389 | } | ||
390 | |||
391 | LOG_INFO("XDS110: disconnected"); | ||
392 | } | ||
393 | |||
394 | static bool usb_read(unsigned char *buffer, int size, int *bytes_read, | ||
395 | int timeout) | ||
396 | { | ||
397 | int result; | ||
398 | |||
399 | if (0 == xds110.dev || 0 == buffer || 0 == bytes_read) | ||
400 | return false; | ||
401 | |||
402 | result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_IN, buffer, size, | ||
403 | bytes_read, timeout); | ||
404 | |||
405 | return (0 == result) ? true : false; | ||
406 | } | ||
407 | |||
408 | static bool usb_write(unsigned char *buffer, int size, int *written) | ||
409 | { | ||
410 | int bytes_written = 0; | ||
411 | int result = LIBUSB_SUCCESS; | ||
412 | int retries = 0; | ||
413 | |||
414 | if (0 == xds110.dev || 0 == buffer) | ||
415 | return false; | ||
416 | |||
417 | result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer, | ||
418 | size, &bytes_written, 0); | ||
419 | |||
420 | while (LIBUSB_ERROR_PIPE == result && retries < 3) { | ||
421 | /* Try clearing the pipe stall and retry transfer */ | ||
422 | libusb_clear_halt(xds110.dev, ENDPOINT_DEBUG_OUT); | ||
423 | result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer, | ||
424 | size, &bytes_written, 0); | ||
425 | retries++; | ||
426 | } | ||
427 | |||
428 | if (0 != written) | ||
429 | *written = bytes_written; | ||
430 | |||
431 | return (0 == result && size == bytes_written) ? true : false; | ||
432 | } | ||
433 | |||
434 | static bool usb_get_response(uint32_t *total_bytes_read, uint32_t timeout) | ||
435 | { | ||
436 | static unsigned char buffer[MAX_PACKET]; | ||
437 | int bytes_read; | ||
438 | uint16_t size; | ||
439 | uint16_t count; | ||
440 | bool success; | ||
441 | |||
442 | /* Set a non-zero timeout to prevent blocking */ | ||
443 | if (0 == timeout) | ||
444 | timeout = DEFAULT_TIMEOUT; | ||
445 | |||
446 | size = 0; | ||
447 | success = true; | ||
448 | while (success) { | ||
449 | success = usb_read(buffer, sizeof(buffer), &bytes_read, timeout); | ||
450 | if (success) { | ||
451 | /* | ||
452 | * Validate that this appears to be a good response packet | ||
453 | * First check it contains enough data for header and error | ||
454 | * code, plus the first character is the start character | ||
455 | */ | ||
456 | if (bytes_read >= 7 && '*' == buffer[0]) { | ||
457 | /* Extract the payload size */ | ||
458 | size = buffer[1] + (buffer[2] << 8); | ||
459 | /* Sanity test on payload size */ | ||
460 | if (USB_PAYLOAD_SIZE >= size && 4 <= size) { | ||
461 | /* Check we didn't get more data than expected */ | ||
462 | if ((bytes_read - 3) <= size) { | ||
463 | /* Packet appears to be valid, move on */ | ||
464 | break; | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | } | ||
469 | /* | ||
470 | * Somehow received an invalid packet, retry till we | ||
471 | * time out or a valid response packet is received | ||
472 | */ | ||
473 | } | ||
474 | |||
475 | /* Abort now if we didn't receive a valid response */ | ||
476 | if (!success) { | ||
477 | if (0 != total_bytes_read) | ||
478 | *total_bytes_read = 0; | ||
479 | return false; | ||
480 | } | ||
481 | |||
482 | /* Build the return payload into xds110.read_payload */ | ||
483 | |||
484 | /* Copy over payload data from received buffer (skipping header) */ | ||
485 | count = 0; | ||
486 | bytes_read -= 3; | ||
487 | memcpy((void *)&xds110.read_payload[count], (void *)&buffer[3], bytes_read); | ||
488 | count += bytes_read; | ||
489 | /* | ||
490 | * Drop timeout to just 1/2 second. Once the XDS110 starts sending | ||
491 | * a response, the remaining packets should arrive in short order | ||
492 | */ | ||
493 | if (timeout > 500) | ||
494 | timeout = 500; /* ms */ | ||
495 | |||
496 | /* If there's more data to retrieve, get it now */ | ||
497 | while ((count < size) && success) { | ||
498 | success = usb_read(buffer, sizeof(buffer), &bytes_read, timeout); | ||
499 | if (success) { | ||
500 | if ((count + bytes_read) > size) { | ||
501 | /* Read too much data, not a valid packet, abort */ | ||
502 | success = false; | ||
503 | } else { | ||
504 | /* Copy this data over to xds110.read_payload */ | ||
505 | memcpy((void *)&xds110.read_payload[count], (void *)buffer, | ||
506 | bytes_read); | ||
507 | count += bytes_read; | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | |||
512 | if (!success) | ||
513 | count = 0; | ||
514 | if (0 != total_bytes_read) | ||
515 | *total_bytes_read = count; | ||
516 | |||
517 | return success; | ||
518 | } | ||
519 | |||
520 | static bool usb_send_command(uint32_t size) | ||
521 | { | ||
522 | int written; | ||
523 | bool success = true; | ||
524 | |||
525 | /* Check the packet length */ | ||
526 | if (size > USB_PAYLOAD_SIZE) | ||
527 | return false; | ||
528 | |||
529 | /* Place the start character into the packet buffer */ | ||
530 | xds110.write_packet[0] = '*'; | ||
531 | |||
532 | /* Place the payload size into the packet buffer */ | ||
533 | xds110.write_packet[1] = (size & 0x00ff) >> 0; | ||
534 | xds110.write_packet[2] = (size & 0xff00) >> 8; | ||
535 | |||
536 | /* Adjust size to include header */ | ||
537 | size += 3; | ||
538 | |||
539 | /* Send the data via the USB connection */ | ||
540 | success = usb_write(xds110.write_packet, (int)size, &written); | ||
541 | |||
542 | /* Check if the correct number of bytes was written */ | ||
543 | if (written != (int)size) | ||
544 | success = false; | ||
545 | |||
546 | return success; | ||
547 | } | ||
548 | |||
549 | /*************************************************************************** | ||
550 | * XDS110 firmware API routines * | ||
551 | * * | ||
552 | * The following functions handle calling into the XDS110 firmware to * | ||
553 | * perform requested debug actions. * | ||
554 | ***************************************************************************/ | ||
555 | |||
556 | static bool xds_execute(uint32_t out_length, uint32_t in_length, | ||
557 | uint32_t attempts, uint32_t timeout) | ||
558 | { | ||
559 | bool done = false; | ||
560 | bool success = true; | ||
561 | int error = 0; | ||
562 | int *error_pntr; | ||
563 | uint32_t bytes_read = 0; | ||
564 | |||
565 | if (0 == xds110.dev) | ||
566 | return false; | ||
567 | |||
568 | while (!done && attempts > 0) { | ||
569 | attempts--; | ||
570 | |||
571 | /* Send command to XDS110 */ | ||
572 | success = usb_send_command(out_length); | ||
573 | |||
574 | if (success) | ||
575 | /* Get response from XDS110 */ | ||
576 | success = usb_get_response(&bytes_read, timeout); | ||
577 | |||
578 | if (success) { | ||
579 | /* Check for valid response from XDS code handling */ | ||
580 | if (bytes_read != in_length) { | ||
581 | /* Unexpected amount of data returned */ | ||
582 | success = false; | ||
583 | } else { | ||
584 | /* Extract error code from return packet */ | ||
585 | error_pntr = (int *)&xds110.read_payload[0]; | ||
586 | error = *error_pntr; | ||
587 | done = true; | ||
588 | } | ||
589 | } | ||
590 | } | ||
591 | |||
592 | if (!success) | ||
593 | error = SC_ERR_XDS110_FAIL; | ||
594 | |||
595 | if (0 != error) | ||
596 | success = false; | ||
597 | |||
598 | return success; | ||
599 | } | ||
600 | |||
601 | static bool xds_connect(void) | ||
602 | { | ||
603 | bool success; | ||
604 | |||
605 | xds110.write_payload[0] = XDS_CONNECT; | ||
606 | |||
607 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
608 | DEFAULT_TIMEOUT); | ||
609 | |||
610 | return success; | ||
611 | } | ||
612 | |||
613 | static bool xds_disconnect(void) | ||
614 | { | ||
615 | bool success; | ||
616 | |||
617 | xds110.write_payload[0] = XDS_DISCONNECT; | ||
618 | |||
619 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
620 | DEFAULT_TIMEOUT); | ||
621 | |||
622 | return success; | ||
623 | } | ||
624 | |||
625 | static bool xds_version(uint32_t *firmware_id, uint16_t *hardware_id) | ||
626 | { | ||
627 | uint32_t *fw_id_pntr; | ||
628 | uint16_t *hw_id_pntr; | ||
629 | |||
630 | fw_id_pntr = (uint32_t *)&xds110.read_payload[XDS_IN_LEN+0]; | ||
631 | hw_id_pntr = (uint16_t *)&xds110.read_payload[XDS_IN_LEN+4]; | ||
632 | |||
633 | bool success; | ||
634 | |||
635 | xds110.write_payload[0] = XDS_VERSION; | ||
636 | |||
637 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN+6, DEFAULT_ATTEMPTS, | ||
638 | DEFAULT_TIMEOUT); | ||
639 | |||
640 | if (success) { | ||
641 | if (0 != firmware_id) | ||
642 | *firmware_id = *fw_id_pntr; | ||
643 | if (0 != hardware_id) | ||
644 | *hardware_id = *hw_id_pntr; | ||
645 | } | ||
646 | |||
647 | return success; | ||
648 | } | ||
649 | |||
650 | static bool xds_set_tck_delay(uint32_t delay) | ||
651 | { | ||
652 | uint32_t *delay_pntr; | ||
653 | |||
654 | delay_pntr = (uint32_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
655 | |||
656 | bool success; | ||
657 | |||
658 | xds110.write_payload[0] = XDS_SET_TCK; | ||
659 | |||
660 | *delay_pntr = delay; | ||
661 | |||
662 | success = xds_execute(XDS_OUT_LEN+4, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
663 | DEFAULT_TIMEOUT); | ||
664 | |||
665 | return success; | ||
666 | } | ||
667 | |||
668 | static bool xds_set_trst(uint8_t trst) | ||
669 | { | ||
670 | uint8_t *trst_pntr; | ||
671 | |||
672 | trst_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
673 | |||
674 | bool success; | ||
675 | |||
676 | xds110.write_payload[0] = XDS_SET_TRST; | ||
677 | |||
678 | *trst_pntr = trst; | ||
679 | |||
680 | success = xds_execute(XDS_OUT_LEN+1, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
681 | DEFAULT_TIMEOUT); | ||
682 | |||
683 | return success; | ||
684 | } | ||
685 | |||
686 | static bool xds_cycle_tck(uint32_t count) | ||
687 | { | ||
688 | uint32_t *count_pntr; | ||
689 | |||
690 | count_pntr = (uint32_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
691 | |||
692 | bool success; | ||
693 | |||
694 | xds110.write_payload[0] = XDS_CYCLE_TCK; | ||
695 | |||
696 | *count_pntr = count; | ||
697 | |||
698 | success = xds_execute(XDS_OUT_LEN+4, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
699 | DEFAULT_TIMEOUT); | ||
700 | |||
701 | return success; | ||
702 | } | ||
703 | |||
704 | static bool xds_goto_state(uint32_t state, uint32_t transit) | ||
705 | { | ||
706 | uint32_t *state_pntr; | ||
707 | uint32_t *transit_pntr; | ||
708 | |||
709 | state_pntr = (uint32_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
710 | transit_pntr = (uint32_t *)&xds110.write_payload[XDS_OUT_LEN+4]; | ||
711 | |||
712 | bool success; | ||
713 | |||
714 | xds110.write_payload[0] = XDS_GOTO_STATE; | ||
715 | |||
716 | *state_pntr = state; | ||
717 | *transit_pntr = transit; | ||
718 | |||
719 | success = xds_execute(XDS_OUT_LEN+8, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
720 | DEFAULT_TIMEOUT); | ||
721 | |||
722 | return success; | ||
723 | } | ||
724 | |||
725 | static bool xds_jtag_scan(uint32_t shift_bits, uint32_t shift_state, | ||
726 | uint32_t begin_transit, uint32_t end_state, uint32_t end_transit, | ||
727 | uint32_t preamble, uint32_t posamble, uint32_t delay_tcks, | ||
728 | uint32_t repeat_count, uint32_t repeat_out_offset, | ||
729 | uint32_t repeat_in_offset, uint8_t *data_out, uint8_t *data_in, | ||
730 | uint32_t bytes_to_send, uint32_t bytes_to_receive) | ||
731 | { | ||
732 | uint16_t *shift_bits_pntr; | ||
733 | uint8_t *shift_state_pntr; | ||
734 | uint8_t *begin_transit_pntr; | ||
735 | uint8_t *end_state_pntr; | ||
736 | uint8_t *end_transit_pntr; | ||
737 | uint16_t *preamble_pntr; | ||
738 | uint16_t *posamble_pntr; | ||
739 | uint16_t *delay_tcks_pntr; | ||
740 | uint16_t *repeat_count_pntr; | ||
741 | uint16_t *repeat_out_offset_pntr; | ||
742 | uint16_t *repeat_in_offset_pntr; | ||
743 | uint8_t *data_out_pntr; | ||
744 | uint8_t *data_in_pntr; | ||
745 | |||
746 | shift_bits_pntr = (uint16_t*)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
747 | shift_state_pntr = (uint8_t*)&xds110.write_payload[XDS_OUT_LEN+2]; | ||
748 | begin_transit_pntr = (uint8_t*)&xds110.write_payload[XDS_OUT_LEN+3]; | ||
749 | end_state_pntr = (uint8_t*)&xds110.write_payload[XDS_OUT_LEN+4]; | ||
750 | end_transit_pntr = (uint8_t*)&xds110.write_payload[XDS_OUT_LEN+5]; | ||
751 | preamble_pntr = (uint16_t*)&xds110.write_payload[XDS_OUT_LEN+6]; | ||
752 | posamble_pntr = (uint16_t*)&xds110.write_payload[XDS_OUT_LEN+8]; | ||
753 | delay_tcks_pntr = (uint16_t*)&xds110.write_payload[XDS_OUT_LEN+10]; | ||
754 | repeat_count_pntr = (uint16_t*)&xds110.write_payload[XDS_OUT_LEN+12]; | ||
755 | repeat_out_offset_pntr = (uint16_t*)&xds110.write_payload[XDS_OUT_LEN+14]; | ||
756 | repeat_in_offset_pntr = (uint16_t*)&xds110.write_payload[XDS_OUT_LEN+16]; | ||
757 | data_out_pntr = (uint8_t*)&xds110.write_payload[XDS_OUT_LEN+18]; | ||
758 | data_in_pntr = (uint8_t*)&xds110.read_payload[XDS_IN_LEN+0]; | ||
759 | |||
760 | bool success; | ||
761 | |||
762 | xds110.write_payload[0] = XDS_JTAG_SCAN; | ||
763 | |||
764 | *shift_bits_pntr = (uint16_t)shift_bits; | ||
765 | *shift_state_pntr = (uint8_t)shift_state; | ||
766 | *begin_transit_pntr = (uint8_t)begin_transit; | ||
767 | *end_state_pntr = (uint8_t)end_state; | ||
768 | *end_transit_pntr = (uint8_t)end_transit; | ||
769 | *preamble_pntr = (uint16_t)preamble; | ||
770 | *posamble_pntr = (uint16_t)posamble; | ||
771 | *delay_tcks_pntr = (uint16_t)delay_tcks; | ||
772 | *repeat_count_pntr = (uint16_t)repeat_count; | ||
773 | *repeat_out_offset_pntr = (uint16_t)repeat_out_offset; | ||
774 | *repeat_in_offset_pntr = (uint16_t)repeat_in_offset; | ||
775 | |||
776 | memcpy((void *)data_out_pntr, (void *)data_out, bytes_to_send); | ||
777 | |||
778 | success = xds_execute(XDS_OUT_LEN+18+bytes_to_send, | ||
779 | XDS_IN_LEN+bytes_to_receive, DEFAULT_ATTEMPTS, DEFAULT_TIMEOUT); | ||
780 | |||
781 | if (success) | ||
782 | memcpy((void *)data_in, (void *)data_in_pntr, bytes_to_receive); | ||
783 | |||
784 | return success; | ||
785 | } | ||
786 | |||
787 | static bool xds_set_srst(uint8_t srst) | ||
788 | { | ||
789 | uint8_t *srst_pntr; | ||
790 | |||
791 | srst_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
792 | |||
793 | bool success; | ||
794 | |||
795 | xds110.write_payload[0] = XDS_SET_SRST; | ||
796 | |||
797 | *srst_pntr = srst; | ||
798 | |||
799 | success = xds_execute(XDS_OUT_LEN+1, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
800 | DEFAULT_TIMEOUT); | ||
801 | |||
802 | return success; | ||
803 | } | ||
804 | |||
805 | static bool cmapi_connect(uint32_t *idcode) | ||
806 | { | ||
807 | uint32_t *idcode_pntr; | ||
808 | |||
809 | idcode_pntr = (uint32_t *)&xds110.read_payload[XDS_IN_LEN+0]; | ||
810 | |||
811 | bool success; | ||
812 | |||
813 | xds110.write_payload[0] = CMAPI_CONNECT; | ||
814 | |||
815 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN+4, DEFAULT_ATTEMPTS, | ||
816 | DEFAULT_TIMEOUT); | ||
817 | |||
818 | if (success) { | ||
819 | if (0 != idcode) | ||
820 | *idcode = *idcode_pntr; | ||
821 | } | ||
822 | |||
823 | return success; | ||
824 | } | ||
825 | |||
826 | static bool cmapi_disconnect(void) | ||
827 | { | ||
828 | bool success; | ||
829 | |||
830 | xds110.write_payload[0] = CMAPI_DISCONNECT; | ||
831 | |||
832 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
833 | DEFAULT_TIMEOUT); | ||
834 | |||
835 | return success; | ||
836 | } | ||
837 | |||
838 | static bool cmapi_acquire(void) | ||
839 | { | ||
840 | bool success; | ||
841 | |||
842 | xds110.write_payload[0] = CMAPI_ACQUIRE; | ||
843 | |||
844 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
845 | DEFAULT_TIMEOUT); | ||
846 | |||
847 | return success; | ||
848 | } | ||
849 | |||
850 | static bool cmapi_release(void) | ||
851 | { | ||
852 | bool success; | ||
853 | |||
854 | xds110.write_payload[0] = CMAPI_RELEASE; | ||
855 | |||
856 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
857 | DEFAULT_TIMEOUT); | ||
858 | |||
859 | return success; | ||
860 | } | ||
861 | |||
862 | static bool cmapi_read_dap_reg(uint32_t type, uint32_t ap_num, | ||
863 | uint32_t address, uint32_t *value) | ||
864 | { | ||
865 | uint8_t *type_pntr; | ||
866 | uint8_t *ap_num_pntr; | ||
867 | uint8_t *address_pntr; | ||
868 | uint8_t *value_pntr; | ||
869 | |||
870 | type_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
871 | ap_num_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+1]; | ||
872 | address_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+2]; | ||
873 | value_pntr = (uint8_t *)&xds110.read_payload[XDS_IN_LEN+0]; | ||
874 | |||
875 | bool success; | ||
876 | |||
877 | xds110.write_payload[0] = CMAPI_REG_READ; | ||
878 | |||
879 | *type_pntr = (uint8_t)type; | ||
880 | *ap_num_pntr = (uint8_t)ap_num; | ||
881 | *address_pntr = (uint8_t)address; | ||
882 | |||
883 | success = xds_execute(XDS_OUT_LEN+3, XDS_IN_LEN+4, DEFAULT_ATTEMPTS, | ||
884 | DEFAULT_TIMEOUT); | ||
885 | |||
886 | if (success) { | ||
887 | if (0 != value) | ||
888 | memcpy((void *)value, (void *)value_pntr, 4); | ||
889 | } | ||
890 | |||
891 | return success; | ||
892 | } | ||
893 | |||
894 | static bool cmapi_write_dap_reg(uint32_t type, uint32_t ap_num, | ||
895 | uint32_t address, uint32_t *value) | ||
896 | { | ||
897 | uint8_t *type_pntr; | ||
898 | uint8_t *ap_num_pntr; | ||
899 | uint8_t *address_pntr; | ||
900 | uint8_t *value_pntr; | ||
901 | |||
902 | type_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
903 | ap_num_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+1]; | ||
904 | address_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+2]; | ||
905 | value_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+3]; | ||
906 | |||
907 | bool success; | ||
908 | |||
909 | if (0 == value) | ||
910 | return false; | ||
911 | |||
912 | xds110.write_payload[0] = CMAPI_REG_WRITE; | ||
913 | |||
914 | *type_pntr = (uint8_t)type; | ||
915 | *ap_num_pntr = (uint8_t)ap_num; | ||
916 | *address_pntr = (uint8_t)address; | ||
917 | |||
918 | memcpy((void *)value_pntr, (void *)value, sizeof(uint32_t)); | ||
919 | |||
920 | success = xds_execute(XDS_OUT_LEN+7, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
921 | DEFAULT_TIMEOUT); | ||
922 | |||
923 | return success; | ||
924 | } | ||
925 | |||
926 | static bool swd_connect(void) | ||
927 | { | ||
928 | bool success; | ||
929 | |||
930 | xds110.write_payload[0] = SWD_CONNECT; | ||
931 | |||
932 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
933 | DEFAULT_TIMEOUT); | ||
934 | |||
935 | return success; | ||
936 | } | ||
937 | |||
938 | static bool swd_disconnect(void) | ||
939 | { | ||
940 | bool success; | ||
941 | |||
942 | xds110.write_payload[0] = SWD_DISCONNECT; | ||
943 | |||
944 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
945 | DEFAULT_TIMEOUT); | ||
946 | |||
947 | return success; | ||
948 | } | ||
949 | |||
950 | static bool cjtag_connect(uint32_t format) | ||
951 | { | ||
952 | uint32_t *format_pntr; | ||
953 | |||
954 | format_pntr = (uint32_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
955 | |||
956 | bool success; | ||
957 | |||
958 | xds110.write_payload[0] = CJTAG_CONNECT; | ||
959 | |||
960 | *format_pntr = format; | ||
961 | |||
962 | success = xds_execute(XDS_OUT_LEN+4, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
963 | DEFAULT_TIMEOUT); | ||
964 | |||
965 | return success; | ||
966 | } | ||
967 | |||
968 | static bool cjtag_disconnect(void) | ||
969 | { | ||
970 | bool success; | ||
971 | |||
972 | xds110.write_payload[0] = CJTAG_DISCONNECT; | ||
973 | |||
974 | success = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS, | ||
975 | DEFAULT_TIMEOUT); | ||
976 | |||
977 | return success; | ||
978 | } | ||
979 | |||
980 | static bool ocd_dap_request(uint8_t *dap_requests, uint32_t request_size, | ||
981 | uint32_t *dap_results, uint32_t result_count) | ||
982 | { | ||
983 | uint8_t *request_pntr; | ||
984 | uint8_t *result_pntr; | ||
985 | |||
986 | request_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
987 | result_pntr = (uint8_t *)&xds110.read_payload[XDS_IN_LEN+0]; | ||
988 | |||
989 | bool success; | ||
990 | |||
991 | if (0 == dap_requests || 0 == dap_results) | ||
992 | return false; | ||
993 | |||
994 | xds110.write_payload[0] = OCD_DAP_REQUEST; | ||
995 | |||
996 | memcpy((void *)request_pntr, (void *)dap_requests, request_size); | ||
997 | |||
998 | success = xds_execute(XDS_OUT_LEN + request_size, | ||
999 | XDS_IN_LEN + (result_count * 4), DEFAULT_ATTEMPTS, | ||
1000 | DEFAULT_TIMEOUT); | ||
1001 | |||
1002 | if (success && (result_count > 0)) | ||
1003 | memcpy((void *)dap_results, (void *)result_pntr, result_count * 4); | ||
1004 | |||
1005 | return success; | ||
1006 | } | ||
1007 | |||
1008 | static bool ocd_scan_request(uint8_t *scan_requests, uint32_t request_size, | ||
1009 | uint8_t *scan_results, uint32_t result_size) | ||
1010 | { | ||
1011 | uint8_t *request_pntr; | ||
1012 | uint8_t *result_pntr; | ||
1013 | |||
1014 | request_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
1015 | result_pntr = (uint8_t *)&xds110.read_payload[XDS_IN_LEN+0]; | ||
1016 | |||
1017 | bool success; | ||
1018 | |||
1019 | if (0 == scan_requests || 0 == scan_results) | ||
1020 | return false; | ||
1021 | |||
1022 | xds110.write_payload[0] = OCD_SCAN_REQUEST; | ||
1023 | |||
1024 | memcpy((void *)request_pntr, (void *)scan_requests, request_size); | ||
1025 | |||
1026 | success = xds_execute(XDS_OUT_LEN + request_size, | ||
1027 | XDS_IN_LEN + result_size, DEFAULT_ATTEMPTS, | ||
1028 | DEFAULT_TIMEOUT); | ||
1029 | |||
1030 | if (success && (result_size > 0)) | ||
1031 | memcpy((void *)scan_results, (void *)result_pntr, result_size); | ||
1032 | |||
1033 | return success; | ||
1034 | } | ||
1035 | |||
1036 | static bool ocd_pathmove(uint32_t num_states, uint8_t *path) | ||
1037 | { | ||
1038 | uint32_t *num_states_pntr; | ||
1039 | uint8_t *path_pntr; | ||
1040 | |||
1041 | num_states_pntr = (uint32_t *)&xds110.write_payload[XDS_OUT_LEN+0]; | ||
1042 | path_pntr = (uint8_t *)&xds110.write_payload[XDS_OUT_LEN+4]; | ||
1043 | |||
1044 | bool success; | ||
1045 | |||
1046 | if (0 == path) | ||
1047 | return false; | ||
1048 | |||
1049 | xds110.write_payload[0] = OCD_PATHMOVE; | ||
1050 | |||
1051 | *num_states_pntr = num_states; | ||
1052 | |||
1053 | memcpy((void *)path_pntr, (void *)path, num_states); | ||
1054 | |||
1055 | success = xds_execute(XDS_OUT_LEN + 4 + num_states, XDS_IN_LEN, | ||
1056 | DEFAULT_ATTEMPTS, DEFAULT_TIMEOUT); | ||
1057 | |||
1058 | return success; | ||
1059 | } | ||
1060 | |||
1061 | /*************************************************************************** | ||
1062 | * swd driver interface * | ||
1063 | * * | ||
1064 | * The following functions provide SWD support to OpenOCD. * | ||
1065 | ***************************************************************************/ | ||
1066 | |||
1067 | static int xds110_swd_init(void) | ||
1068 | { | ||
1069 | xds110.is_swd_mode = true; | ||
1070 | return ERROR_OK; | ||
1071 | } | ||
1072 | |||
1073 | static int xds110_swd_switch_seq(enum swd_special_seq seq) | ||
1074 | { | ||
1075 | /* Not used for XDS110. The switch is handled during xds110_init() */ | ||
1076 | return ERROR_OK; | ||
1077 | } | ||
1078 | |||
1079 | static bool xds110_legacy_read_reg(uint8_t cmd, uint32_t *value) | ||
1080 | { | ||
1081 | /* Make sure this is a read request */ | ||
1082 | bool is_read_request = (0 != (SWD_CMD_RnW & cmd)); | ||
1083 | /* Determine whether this is a DP or AP register access */ | ||
1084 | uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP; | ||
1085 | /* Determine the AP number from cached SELECT value */ | ||
1086 | uint32_t ap_num = (xds110.select & 0xff000000) >> 24; | ||
1087 | /* Extract register address from command */ | ||
1088 | uint32_t address = ((cmd & SWD_CMD_A32) >> 1); | ||
1089 | /* Extract bank address from cached SELECT value */ | ||
1090 | uint32_t bank = (xds110.select & 0x000000f0); | ||
1091 | |||
1092 | uint32_t reg_value = 0; | ||
1093 | uint32_t temp_value = 0; | ||
1094 | |||
1095 | bool success; | ||
1096 | |||
1097 | if (!is_read_request) | ||
1098 | return false; | ||
1099 | |||
1100 | if (DAP_AP == type) { | ||
1101 | /* Add bank address to register address for CMAPI call */ | ||
1102 | address |= bank; | ||
1103 | } | ||
1104 | |||
1105 | if (DAP_DP == type && DAP_DP_RDBUFF == address && xds110.use_rdbuff) { | ||
1106 | /* If RDBUFF is cached and this is a DP RDBUFF read, use the cache */ | ||
1107 | reg_value = xds110.rdbuff; | ||
1108 | success = true; | ||
1109 | } else if (DAP_AP == type && DAP_AP_DRW == address && xds110.use_rdbuff) { | ||
1110 | /* If RDBUFF is cached and this is an AP DRW read, use the cache, */ | ||
1111 | /* but still call into the firmware to get the next read. */ | ||
1112 | reg_value = xds110.rdbuff; | ||
1113 | success = cmapi_read_dap_reg(type, ap_num, address, &temp_value); | ||
1114 | } else { | ||
1115 | success = cmapi_read_dap_reg(type, ap_num, address, &temp_value); | ||
1116 | if (success) | ||
1117 | reg_value = temp_value; | ||
1118 | } | ||
1119 | |||
1120 | /* Mark that we have consumed or invalidated the RDBUFF cache */ | ||
1121 | xds110.use_rdbuff = false; | ||
1122 | |||
1123 | /* Handle result of read attempt */ | ||
1124 | if (!success) | ||
1125 | LOG_ERROR("XDS110: failed to read DAP register"); | ||
1126 | else if (0 != value) | ||
1127 | *value = reg_value; | ||
1128 | |||
1129 | if (success && DAP_AP == type) { | ||
1130 | /* | ||
1131 | * On a successful DAP AP read, we actually have the value from RDBUFF, | ||
1132 | * the firmware will have run the AP request and made the RDBUFF read | ||
1133 | */ | ||
1134 | xds110.use_rdbuff = true; | ||
1135 | xds110.rdbuff = temp_value; | ||
1136 | } | ||
1137 | |||
1138 | return success; | ||
1139 | } | ||
1140 | |||
1141 | static bool xds110_legacy_write_reg(uint8_t cmd, uint32_t value) | ||
1142 | { | ||
1143 | /* Make sure this isn't a read request */ | ||
1144 | bool is_read_request = (0 != (SWD_CMD_RnW & cmd)); | ||
1145 | /* Determine whether this is a DP or AP register access */ | ||
1146 | uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP; | ||
1147 | /* Determine the AP number from cached SELECT value */ | ||
1148 | uint32_t ap_num = (xds110.select & 0xff000000) >> 24; | ||
1149 | /* Extract register address from command */ | ||
1150 | uint32_t address = ((cmd & SWD_CMD_A32) >> 1); | ||
1151 | /* Extract bank address from cached SELECT value */ | ||
1152 | uint32_t bank = (xds110.select & 0x000000f0); | ||
1153 | |||
1154 | bool success; | ||
1155 | |||
1156 | if (is_read_request) | ||
1157 | return false; | ||
1158 | |||
1159 | /* Invalidate the RDBUFF cache */ | ||
1160 | xds110.use_rdbuff = false; | ||
1161 | |||
1162 | if (DAP_AP == type) { | ||
1163 | /* Add bank address to register address for CMAPI call */ | ||
1164 | address |= bank; | ||
1165 | /* Any write to an AP register invalidates the firmware's cache */ | ||
1166 | xds110.is_ap_dirty = true; | ||
1167 | } else if (DAP_DP_SELECT == address) { | ||
1168 | /* Any write to the SELECT register invalidates the firmware's cache */ | ||
1169 | xds110.is_ap_dirty = true; | ||
1170 | } | ||
1171 | |||
1172 | success = cmapi_write_dap_reg(type, ap_num, address, &value); | ||
1173 | |||
1174 | if (!success) { | ||
1175 | LOG_ERROR("XDS110: failed to write DAP register"); | ||
1176 | } else { | ||
1177 | /* | ||
1178 | * If the debugger wrote to SELECT, cache the value | ||
1179 | * to use to build the apNum and address values above | ||
1180 | */ | ||
1181 | if ((DAP_DP == type) && (DAP_DP_SELECT == address)) { | ||
1182 | xds110.select = value; | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1186 | return success; | ||
1187 | } | ||
1188 | |||
1189 | static int xds110_swd_run_queue(void) | ||
1190 | { | ||
1191 | static uint32_t dap_results[MAX_RESULT_QUEUE]; | ||
1192 | uint8_t cmd; | ||
1193 | uint32_t request; | ||
1194 | uint32_t result; | ||
1195 | uint32_t value; | ||
1196 | bool success = true; | ||
1197 | |||
1198 | if (0 == xds110.txn_request_size) | ||
1199 | return ERROR_OK; | ||
1200 | |||
1201 | /* Terminate request queue */ | ||
1202 | xds110.txn_requests[xds110.txn_request_size++] = 0; | ||
1203 | |||
1204 | if (xds110.firmware >= OCD_FIRMWARE_VERSION) { | ||
1205 | /* XDS110 firmware has the API to directly handle the queue */ | ||
1206 | success = ocd_dap_request(xds110.txn_requests, | ||
1207 | xds110.txn_request_size, dap_results, xds110.txn_result_count); | ||
1208 | } else { | ||
1209 | /* Legacy firmware needs to handle queue via discrete DAP calls */ | ||
1210 | request = 0; | ||
1211 | result = 0; | ||
1212 | while (xds110.txn_requests[request] != 0) { | ||
1213 | cmd = xds110.txn_requests[request++]; | ||
1214 | if (0 == (SWD_CMD_RnW & cmd)) { | ||
1215 | /* DAP register write command */ | ||
1216 | value = (uint32_t)(xds110.txn_requests[request++]) << 0; | ||
1217 | value |= (uint32_t)(xds110.txn_requests[request++]) << 8; | ||
1218 | value |= (uint32_t)(xds110.txn_requests[request++]) << 16; | ||
1219 | value |= (uint32_t)(xds110.txn_requests[request++]) << 24; | ||
1220 | if (success) | ||
1221 | success = xds110_legacy_write_reg(cmd, value); | ||
1222 | } else { | ||
1223 | /* DAP register read command */ | ||
1224 | value = 0; | ||
1225 | if (success) | ||
1226 | success = xds110_legacy_read_reg(cmd, &value); | ||
1227 | dap_results[result++] = value; | ||
1228 | } | ||
1229 | } | ||
1230 | } | ||
1231 | |||
1232 | /* Transfer results into caller's buffers */ | ||
1233 | for (result = 0; result < xds110.txn_result_count; result++) | ||
1234 | if (0 != xds110.txn_dap_results[result]) | ||
1235 | *xds110.txn_dap_results[result] = dap_results[result]; | ||
1236 | |||
1237 | xds110.txn_request_size = 0; | ||
1238 | xds110.txn_result_size = 0; | ||
1239 | xds110.txn_result_count = 0; | ||
1240 | |||
1241 | return (success) ? ERROR_OK : ERROR_FAIL; | ||
1242 | } | ||
1243 | |||
1244 | static void xds110_swd_queue_cmd(uint8_t cmd, uint32_t *value) | ||
1245 | { | ||
1246 | /* Check if this is a read or write request */ | ||
1247 | bool is_read_request = (0 != (SWD_CMD_RnW & cmd)); | ||
1248 | /* Determine whether this is a DP or AP register access */ | ||
1249 | uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP; | ||
1250 | /* Extract register address from command */ | ||
1251 | uint32_t address = ((cmd & SWD_CMD_A32) >> 1); | ||
1252 | uint32_t request_size = (is_read_request) ? 1 : 5; | ||
1253 | |||
1254 | /* Check if new request would be too large to fit */ | ||
1255 | if (((xds110.txn_request_size + request_size + 1) > MAX_DATA_BLOCK) || | ||
1256 | ((xds110.txn_result_count + 1) > MAX_RESULT_QUEUE)) | ||
1257 | xds110_swd_run_queue(); | ||
1258 | |||
1259 | /* Set the START bit in cmd to ensure cmd is not zero */ | ||
1260 | /* (a value of zero is used to terminate the buffer) */ | ||
1261 | cmd |= SWD_CMD_START; | ||
1262 | |||
1263 | /* Add request to queue; queue is built marshalled for XDS110 call */ | ||
1264 | if (is_read_request) { | ||
1265 | /* Queue read request, save pointer to pass back result */ | ||
1266 | xds110.txn_requests[xds110.txn_request_size++] = cmd; | ||
1267 | xds110.txn_dap_results[xds110.txn_result_count++] = value; | ||
1268 | xds110.txn_result_size += 4; | ||
1269 | } else { | ||
1270 | /* Check for and prevent sticky overrun detection */ | ||
1271 | if (DAP_DP == type && DAP_DP_CTRL == address && | ||
1272 | (*value & CORUNDETECT)) { | ||
1273 | LOG_DEBUG("XDS110: refusing to enable sticky overrun detection"); | ||
1274 | *value &= ~CORUNDETECT; | ||
1275 | } | ||
1276 | /* Queue write request, add value directly to queue buffer */ | ||
1277 | xds110.txn_requests[xds110.txn_request_size++] = cmd; | ||
1278 | xds110.txn_requests[xds110.txn_request_size++] = (*value >> 0) & 0xff; | ||
1279 | xds110.txn_requests[xds110.txn_request_size++] = (*value >> 8) & 0xff; | ||
1280 | xds110.txn_requests[xds110.txn_request_size++] = (*value >> 16) & 0xff; | ||
1281 | xds110.txn_requests[xds110.txn_request_size++] = (*value >> 24) & 0xff; | ||
1282 | } | ||
1283 | } | ||
1284 | |||
1285 | static void xds110_swd_read_reg(uint8_t cmd, uint32_t *value, | ||
1286 | uint32_t ap_delay_clk) | ||
1287 | { | ||
1288 | xds110_swd_queue_cmd(cmd, value); | ||
1289 | } | ||
1290 | static void xds110_swd_write_reg(uint8_t cmd, uint32_t value, | ||
1291 | uint32_t ap_delay_clk) | ||
1292 | { | ||
1293 | xds110_swd_queue_cmd(cmd, &value); | ||
1294 | } | ||
1295 | |||
1296 | /*************************************************************************** | ||
1297 | * jtag interface * | ||
1298 | * * | ||
1299 | * The following functions provide XDS110 interface to OpenOCD. * | ||
1300 | ***************************************************************************/ | ||
1301 | |||
1302 | static void xds110_show_info(void) | ||
1303 | { | ||
1304 | uint32_t firmware = xds110.firmware; | ||
1305 | |||
1306 | LOG_INFO("XDS110: firmware version = %d.%d.%d.%d", | ||
1307 | (((firmware >> 28) & 0xf) * 10) + ((firmware >> 24) & 0xf), | ||
1308 | (((firmware >> 20) & 0xf) * 10) + ((firmware >> 16) & 0xf), | ||
1309 | (((firmware >> 12) & 0xf) * 10) + ((firmware >> 8) & 0xf), | ||
1310 | (((firmware >> 4) & 0xf) * 10) + ((firmware >> 0) & 0xf)); | ||
1311 | LOG_INFO("XDS110: hardware version = 0x%04x", xds110.hardware); | ||
1312 | if (0 != xds110.serial[0]) | ||
1313 | LOG_INFO("XDS110: serial number = %s)", xds110.serial); | ||
1314 | if (xds110.is_swd_mode) { | ||
1315 | LOG_INFO("XDS110: connected to target via SWD"); | ||
1316 | LOG_INFO("XDS110: SWCLK set to %d kHz", xds110.speed); | ||
1317 | } else { | ||
1318 | LOG_INFO("XDS110: connected to target via JTAG"); | ||
1319 | LOG_INFO("XDS110: TCK set to %d kHz", xds110.speed); | ||
1320 | } | ||
1321 | |||
1322 | /* Alert user that there's a better firmware to use */ | ||
1323 | if (firmware < OCD_FIRMWARE_VERSION) { | ||
1324 | LOG_WARNING("XDS110: the firmware is not optimized for OpenOCD"); | ||
1325 | LOG_WARNING(OCD_FIRMWARE_UPGRADE); | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | static int xds110_quit(void) | ||
1330 | { | ||
1331 | if (xds110.is_cmapi_acquired) { | ||
1332 | (void)cmapi_release(); | ||
1333 | xds110.is_cmapi_acquired = false; | ||
1334 | } | ||
1335 | if (xds110.is_cmapi_connected) { | ||
1336 | (void)cmapi_disconnect(); | ||
1337 | xds110.is_cmapi_connected = false; | ||
1338 | } | ||
1339 | if (xds110.is_connected) { | ||
1340 | if (xds110.is_swd_mode) { | ||
1341 | /* Switch out of SWD mode */ | ||
1342 | (void)swd_disconnect(); | ||
1343 | } else { | ||
1344 | /* Switch out of cJTAG mode */ | ||
1345 | (void)cjtag_disconnect(); | ||
1346 | } | ||
1347 | /* Tell firmware we're disconnecting */ | ||
1348 | (void)xds_disconnect(); | ||
1349 | xds110.is_connected = false; | ||
1350 | } | ||
1351 | /* Close down the USB connection to the XDS110 debug probe */ | ||
1352 | usb_disconnect(); | ||
1353 | |||
1354 | return ERROR_OK; | ||
1355 | } | ||
1356 | |||
1357 | static int xds110_init(void) | ||
1358 | { | ||
1359 | bool success; | ||
1360 | |||
1361 | /* Establish USB connection to the XDS110 debug probe */ | ||
1362 | success = usb_connect(); | ||
1363 | |||
1364 | if (success) { | ||
1365 | /* Send connect message to XDS110 firmware */ | ||
1366 | success = xds_connect(); | ||
1367 | if (success) xds110.is_connected = true; | ||
1368 | } | ||
1369 | |||
1370 | if (success) { | ||
1371 | uint32_t firmware; | ||
1372 | uint16_t hardware; | ||
1373 | |||
1374 | /* Retrieve version IDs from firmware */ | ||
1375 | /* Version numbers are stored in BCD format */ | ||
1376 | success = xds_version(&firmware, &hardware); | ||
1377 | if (success) { | ||
1378 | /* Save the firmware and hardware version */ | ||
1379 | xds110.firmware = firmware; | ||
1380 | xds110.hardware = hardware; | ||
1381 | } | ||
1382 | } | ||
1383 | |||
1384 | if (success) { | ||
1385 | success = xds_set_trst(0); | ||
1386 | if (success) | ||
1387 | success = xds_cycle_tck(50); | ||
1388 | if (success) | ||
1389 | success = xds_set_trst(1); | ||
1390 | if (success) | ||
1391 | success = xds_cycle_tck(50); | ||
1392 | } | ||
1393 | |||
1394 | if (success) { | ||
1395 | if (xds110.is_swd_mode) { | ||
1396 | /* Switch to SWD if needed */ | ||
1397 | success = swd_connect(); | ||
1398 | } else { | ||
1399 | success = cjtag_connect(MODE_JTAG); | ||
1400 | } | ||
1401 | } | ||
1402 | |||
1403 | if (success && xds110.is_swd_mode) { | ||
1404 | uint32_t idcode; | ||
1405 | |||
1406 | /* Connect to CMAPI interface in XDS110 */ | ||
1407 | success = cmapi_connect(&idcode); | ||
1408 | |||
1409 | /* Acquire exclusive access to CMAPI interface */ | ||
1410 | if (success) { | ||
1411 | success = cmapi_acquire(); | ||
1412 | if (success) | ||
1413 | xds110.is_cmapi_acquired = true; | ||
1414 | } | ||
1415 | } | ||
1416 | |||
1417 | if (!success) | ||
1418 | xds110_quit(); | ||
1419 | |||
1420 | if (success) | ||
1421 | xds110_show_info(); | ||
1422 | |||
1423 | return (success) ? ERROR_OK : ERROR_FAIL; | ||
1424 | } | ||
1425 | |||
1426 | static void xds110_legacy_scan(uint32_t shift_state, uint32_t total_bits, | ||
1427 | uint32_t end_state, uint8_t *data_out, uint8_t *data_in) | ||
1428 | { | ||
1429 | uint32_t total_bytes; | ||
1430 | |||
1431 | if (total_bits == 0) | ||
1432 | return; | ||
1433 | |||
1434 | total_bytes = DIV_ROUND_UP(total_bits, 8); | ||
1435 | |||
1436 | (void)xds_jtag_scan(total_bits, shift_state, XDS_JTAG_TRANSIT_QUICKEST, | ||
1437 | end_state, XDS_JTAG_TRANSIT_QUICKEST, 0, 0, 0, 1, total_bytes, | ||
1438 | total_bytes, data_out, data_in, total_bytes, total_bytes); | ||
1439 | |||
1440 | return; | ||
1441 | } | ||
1442 | |||
1443 | static void xds110_legacy_runtest(uint32_t clocks, uint32_t end_state) | ||
1444 | { | ||
1445 | xds_goto_state(XDS_JTAG_STATE_IDLE, XDS_JTAG_TRANSIT_QUICKEST); | ||
1446 | xds_cycle_tck(clocks); | ||
1447 | xds_goto_state(end_state, XDS_JTAG_TRANSIT_QUICKEST); | ||
1448 | return; | ||
1449 | } | ||
1450 | |||
1451 | static void xds110_legacy_stableclocks(uint32_t clocks) | ||
1452 | { | ||
1453 | xds_cycle_tck(clocks); | ||
1454 | return; | ||
1455 | } | ||
1456 | |||
1457 | static void xds110_flush(void) | ||
1458 | { | ||
1459 | uint8_t command; | ||
1460 | uint32_t clocks; | ||
1461 | uint32_t shift_state; | ||
1462 | uint32_t end_state; | ||
1463 | uint32_t bits; | ||
1464 | uint32_t bytes; | ||
1465 | uint32_t request; | ||
1466 | uint32_t result; | ||
1467 | uint8_t *data_out; | ||
1468 | uint8_t data_in[MAX_DATA_BLOCK]; | ||
1469 | uint8_t *data_pntr; | ||
1470 | |||
1471 | if (0 == xds110.txn_request_size) | ||
1472 | return; | ||
1473 | |||
1474 | /* Terminate request queue */ | ||
1475 | xds110.txn_requests[xds110.txn_request_size++] = 0; | ||
1476 | |||
1477 | if (xds110.firmware >= OCD_FIRMWARE_VERSION) { | ||
1478 | /* XDS110 firmware has the API to directly handle the queue */ | ||
1479 | (void)ocd_scan_request(xds110.txn_requests, xds110.txn_request_size, | ||
1480 | data_in, xds110.txn_result_size); | ||
1481 | } else { | ||
1482 | /* Legacy firmware needs to handle queue via discrete JTAG calls */ | ||
1483 | request = 0; | ||
1484 | result = 0; | ||
1485 | while (xds110.txn_requests[request] != 0) { | ||
1486 | command = xds110.txn_requests[request++]; | ||
1487 | switch (command) { | ||
1488 | case CMD_IR_SCAN: | ||
1489 | case CMD_DR_SCAN: | ||
1490 | if (command == CMD_IR_SCAN) | ||
1491 | shift_state = XDS_JTAG_STATE_SHIFT_IR; | ||
1492 | else | ||
1493 | shift_state = XDS_JTAG_STATE_SHIFT_DR; | ||
1494 | end_state = (uint32_t)(xds110.txn_requests[request++]); | ||
1495 | bits = (uint32_t)(xds110.txn_requests[request++]) << 0; | ||
1496 | bits |= (uint32_t)(xds110.txn_requests[request++]) << 8; | ||
1497 | data_out = &xds110.txn_requests[request]; | ||
1498 | bytes = DIV_ROUND_UP(bits, 8); | ||
1499 | xds110_legacy_scan(shift_state, bits, end_state, data_out, | ||
1500 | &data_in[result]); | ||
1501 | result += bytes; | ||
1502 | request += bytes; | ||
1503 | break; | ||
1504 | case CMD_RUNTEST: | ||
1505 | clocks = (uint32_t)(xds110.txn_requests[request++]) << 0; | ||
1506 | clocks |= (uint32_t)(xds110.txn_requests[request++]) << 8; | ||
1507 | clocks |= (uint32_t)(xds110.txn_requests[request++]) << 16; | ||
1508 | clocks |= (uint32_t)(xds110.txn_requests[request++]) << 24; | ||
1509 | end_state = (uint32_t)xds110.txn_requests[request++]; | ||
1510 | xds110_legacy_runtest(clocks, end_state); | ||
1511 | break; | ||
1512 | case CMD_STABLECLOCKS: | ||
1513 | clocks = (uint32_t)(xds110.txn_requests[request++]) << 0; | ||
1514 | clocks |= (uint32_t)(xds110.txn_requests[request++]) << 8; | ||
1515 | clocks |= (uint32_t)(xds110.txn_requests[request++]) << 16; | ||
1516 | clocks |= (uint32_t)(xds110.txn_requests[request++]) << 24; | ||
1517 | xds110_legacy_stableclocks(clocks); | ||
1518 | break; | ||
1519 | default: | ||
1520 | LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered", | ||
1521 | command); | ||
1522 | exit(-1); | ||
1523 | break; | ||
1524 | } | ||
1525 | } | ||
1526 | } | ||
1527 | |||
1528 | /* Transfer results into caller's buffers from data_in buffer */ | ||
1529 | bits = 0; /* Bit offset into current scan result */ | ||
1530 | data_pntr = data_in; | ||
1531 | for (result = 0; result < xds110.txn_result_count; result++) { | ||
1532 | if (xds110.txn_scan_results[result].first) { | ||
1533 | if (bits != 0) { | ||
1534 | bytes = DIV_ROUND_UP(bits, 8); | ||
1535 | data_pntr += bytes; | ||
1536 | } | ||
1537 | bits = 0; | ||
1538 | } | ||
1539 | if (xds110.txn_scan_results[result].buffer != 0) | ||
1540 | bit_copy(xds110.txn_scan_results[result].buffer, 0, data_pntr, | ||
1541 | bits, xds110.txn_scan_results[result].num_bits); | ||
1542 | bits += xds110.txn_scan_results[result].num_bits; | ||
1543 | } | ||
1544 | |||
1545 | xds110.txn_request_size = 0; | ||
1546 | xds110.txn_result_size = 0; | ||
1547 | xds110.txn_result_count = 0; | ||
1548 | } | ||
1549 | |||
1550 | static void xds110_execute_reset(struct jtag_command *cmd) | ||
1551 | { | ||
1552 | char trst; | ||
1553 | char srst; | ||
1554 | |||
1555 | if (cmd->cmd.reset->trst != -1) { | ||
1556 | if (cmd->cmd.reset->trst == 0) { | ||
1557 | /* Deassert nTRST (active low) */ | ||
1558 | trst = 1; | ||
1559 | } else { | ||
1560 | /* Assert nTRST (active low) */ | ||
1561 | trst = 0; | ||
1562 | } | ||
1563 | (void)xds_set_trst(trst); | ||
1564 | } | ||
1565 | |||
1566 | if (cmd->cmd.reset->srst != -1) { | ||
1567 | if (cmd->cmd.reset->srst == 0) { | ||
1568 | /* Deassert nSRST (active low) */ | ||
1569 | srst = 1; | ||
1570 | } else { | ||
1571 | /* Assert nSRST (active low) */ | ||
1572 | srst = 0; | ||
1573 | } | ||
1574 | (void)xds_set_srst(srst); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | static void xds110_execute_sleep(struct jtag_command *cmd) | ||
1579 | { | ||
1580 | jtag_sleep(cmd->cmd.sleep->us); | ||
1581 | return; | ||
1582 | } | ||
1583 | |||
1584 | static void xds110_execute_tlr_reset(struct jtag_command *cmd) | ||
1585 | { | ||
1586 | (void)xds_goto_state(XDS_JTAG_STATE_RESET, XDS_JTAG_TRANSIT_QUICKEST); | ||
1587 | |||
1588 | return; | ||
1589 | } | ||
1590 | |||
1591 | static void xds110_execute_pathmove(struct jtag_command *cmd) | ||
1592 | { | ||
1593 | uint32_t i; | ||
1594 | uint32_t num_states; | ||
1595 | uint8_t *path; | ||
1596 | |||
1597 | num_states = (uint32_t)cmd->cmd.pathmove->num_states; | ||
1598 | |||
1599 | if (num_states == 0) | ||
1600 | return; | ||
1601 | |||
1602 | path = (uint8_t *)malloc(num_states * sizeof(uint8_t)); | ||
1603 | if (path == 0) { | ||
1604 | LOG_ERROR("XDS110: unable to allocate memory"); | ||
1605 | return; | ||
1606 | } | ||
1607 | |||
1608 | /* Convert requested path states into XDS API states */ | ||
1609 | for (i = 0; i < num_states; i++) | ||
1610 | path[i] = (uint8_t)xds_jtag_state[cmd->cmd.pathmove->path[i]]; | ||
1611 | |||
1612 | if (xds110.firmware >= OCD_FIRMWARE_VERSION) { | ||
1613 | /* Updated firmware fully supports pathmove */ | ||
1614 | (void)ocd_pathmove(num_states, path); | ||
1615 | } else { | ||
1616 | /* Notify user that legacy firmware simply cannot handle pathmove */ | ||
1617 | LOG_ERROR("XDS110: the firmware does not support pathmove command"); | ||
1618 | LOG_ERROR(OCD_FIRMWARE_UPGRADE); | ||
1619 | /* If pathmove is required, then debug is not possible */ | ||
1620 | exit(-1); | ||
1621 | } | ||
1622 | |||
1623 | free((void *)path); | ||
1624 | |||
1625 | return; | ||
1626 | } | ||
1627 | |||
1628 | static void xds110_queue_scan(struct jtag_command *cmd) | ||
1629 | { | ||
1630 | int i; | ||
1631 | uint32_t offset; | ||
1632 | uint32_t total_fields; | ||
1633 | uint32_t total_bits; | ||
1634 | uint32_t total_bytes; | ||
1635 | uint8_t end_state; | ||
1636 | uint8_t *buffer; | ||
1637 | |||
1638 | /* Calculate the total number of bits to scan */ | ||
1639 | total_bits = 0; | ||
1640 | total_fields = 0; | ||
1641 | for (i = 0; i < cmd->cmd.scan->num_fields; i++) { | ||
1642 | total_fields++; | ||
1643 | total_bits += (uint32_t)cmd->cmd.scan->fields[i].num_bits; | ||
1644 | } | ||
1645 | |||
1646 | if (total_bits == 0) | ||
1647 | return; | ||
1648 | |||
1649 | total_bytes = DIV_ROUND_UP(total_bits, 8); | ||
1650 | |||
1651 | /* Check if new request would be too large to fit */ | ||
1652 | if (((xds110.txn_request_size + 1 + total_bytes + sizeof(end_state) + 1) | ||
1653 | > MAX_DATA_BLOCK) || ((xds110.txn_result_count + total_fields) > | ||
1654 | MAX_RESULT_QUEUE)) | ||
1655 | xds110_flush(); | ||
1656 | |||
1657 | /* Check if this single request is too large to fit */ | ||
1658 | if ((1 + total_bytes + sizeof(end_state) + 1) > MAX_DATA_BLOCK) { | ||
1659 | LOG_ERROR("BUG: JTAG scan request is too large to handle (%d bits)", | ||
1660 | total_bits); | ||
1661 | /* Failing to run this scan mucks up debug on this target */ | ||
1662 | exit(-1); | ||
1663 | } | ||
1664 | |||
1665 | if (cmd->cmd.scan->ir_scan) | ||
1666 | xds110.txn_requests[xds110.txn_request_size++] = CMD_IR_SCAN; | ||
1667 | else | ||
1668 | xds110.txn_requests[xds110.txn_request_size++] = CMD_DR_SCAN; | ||
1669 | |||
1670 | end_state = (uint8_t)xds_jtag_state[cmd->cmd.scan->end_state]; | ||
1671 | xds110.txn_requests[xds110.txn_request_size++] = end_state; | ||
1672 | |||
1673 | xds110.txn_requests[xds110.txn_request_size++] = (total_bits >> 0) & 0xff; | ||
1674 | xds110.txn_requests[xds110.txn_request_size++] = (total_bits >> 8) & 0xff; | ||
1675 | |||
1676 | /* Build request data by flattening fields into single buffer */ | ||
1677 | /* also populate the results array to return the results when run */ | ||
1678 | offset = 0; | ||
1679 | buffer = &xds110.txn_requests[xds110.txn_request_size]; | ||
1680 | /* Clear data out buffer to default value of all zeros */ | ||
1681 | memset((void *)buffer, 0x00, total_bytes); | ||
1682 | for (i = 0; i < cmd->cmd.scan->num_fields; i++) { | ||
1683 | if (cmd->cmd.scan->fields[i].out_value != 0) { | ||
1684 | /* Copy over data to scan out into request buffer */ | ||
1685 | bit_copy(buffer, offset, cmd->cmd.scan->fields[i].out_value, 0, | ||
1686 | cmd->cmd.scan->fields[i].num_bits); | ||
1687 | } | ||
1688 | offset += cmd->cmd.scan->fields[i].num_bits; | ||
1689 | xds110.txn_scan_results[xds110.txn_result_count].first = (i == 0); | ||
1690 | xds110.txn_scan_results[xds110.txn_result_count].num_bits = | ||
1691 | cmd->cmd.scan->fields[i].num_bits; | ||
1692 | xds110.txn_scan_results[xds110.txn_result_count++].buffer = | ||
1693 | cmd->cmd.scan->fields[i].in_value; | ||
1694 | } | ||
1695 | xds110.txn_request_size += total_bytes; | ||
1696 | xds110.txn_result_size += total_bytes; | ||
1697 | |||
1698 | return; | ||
1699 | } | ||
1700 | |||
1701 | static void xds110_queue_runtest(struct jtag_command *cmd) | ||
1702 | { | ||
1703 | uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles; | ||
1704 | uint8_t end_state = (uint8_t)xds_jtag_state[cmd->cmd.runtest->end_state]; | ||
1705 | |||
1706 | /* Check if new request would be too large to fit */ | ||
1707 | if ((xds110.txn_request_size + 1 + sizeof(clocks) + sizeof(end_state) + 1) | ||
1708 | > MAX_DATA_BLOCK) | ||
1709 | xds110_flush(); | ||
1710 | |||
1711 | clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles; | ||
1712 | end_state = (uint8_t)xds_jtag_state[cmd->cmd.runtest->end_state]; | ||
1713 | |||
1714 | /* Queue request and cycle count directly to queue buffer */ | ||
1715 | xds110.txn_requests[xds110.txn_request_size++] = CMD_RUNTEST; | ||
1716 | xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 0) & 0xff; | ||
1717 | xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 8) & 0xff; | ||
1718 | xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff; | ||
1719 | xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff; | ||
1720 | xds110.txn_requests[xds110.txn_request_size++] = end_state; | ||
1721 | |||
1722 | return; | ||
1723 | } | ||
1724 | |||
1725 | static void xds110_queue_stableclocks(struct jtag_command *cmd) | ||
1726 | { | ||
1727 | uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles; | ||
1728 | |||
1729 | /* Check if new request would be too large to fit */ | ||
1730 | if ((xds110.txn_request_size + 1 + sizeof(clocks) + 1) > MAX_DATA_BLOCK) | ||
1731 | xds110_flush(); | ||
1732 | |||
1733 | /* Queue request and cycle count directly to queue buffer */ | ||
1734 | xds110.txn_requests[xds110.txn_request_size++] = CMD_STABLECLOCKS; | ||
1735 | xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 0) & 0xff; | ||
1736 | xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 8) & 0xff; | ||
1737 | xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff; | ||
1738 | xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff; | ||
1739 | |||
1740 | return; | ||
1741 | } | ||
1742 | |||
1743 | static void xds110_execute_command(struct jtag_command *cmd) | ||
1744 | { | ||
1745 | switch (cmd->type) { | ||
1746 | case JTAG_RESET: | ||
1747 | xds110_flush(); | ||
1748 | xds110_execute_reset(cmd); | ||
1749 | break; | ||
1750 | case JTAG_SLEEP: | ||
1751 | xds110_flush(); | ||
1752 | xds110_execute_sleep(cmd); | ||
1753 | break; | ||
1754 | case JTAG_TLR_RESET: | ||
1755 | xds110_flush(); | ||
1756 | xds110_execute_tlr_reset(cmd); | ||
1757 | break; | ||
1758 | case JTAG_PATHMOVE: | ||
1759 | xds110_flush(); | ||
1760 | xds110_execute_pathmove(cmd); | ||
1761 | break; | ||
1762 | case JTAG_SCAN: | ||
1763 | xds110_queue_scan(cmd); | ||
1764 | break; | ||
1765 | case JTAG_RUNTEST: | ||
1766 | xds110_queue_runtest(cmd); | ||
1767 | break; | ||
1768 | case JTAG_STABLECLOCKS: | ||
1769 | xds110_queue_stableclocks(cmd); | ||
1770 | break; | ||
1771 | case JTAG_TMS: | ||
1772 | default: | ||
1773 | LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered", | ||
1774 | cmd->type); | ||
1775 | exit(-1); | ||
1776 | } | ||
1777 | } | ||
1778 | |||
1779 | static int xds110_execute_queue(void) | ||
1780 | { | ||
1781 | struct jtag_command *cmd = jtag_command_queue; | ||
1782 | |||
1783 | while (cmd != 0) { | ||
1784 | xds110_execute_command(cmd); | ||
1785 | cmd = cmd->next; | ||
1786 | } | ||
1787 | |||
1788 | xds110_flush(); | ||
1789 | |||
1790 | return ERROR_OK; | ||
1791 | } | ||
1792 | |||
1793 | static int xds110_speed(int speed) | ||
1794 | { | ||
1795 | bool success; | ||
1796 | |||
1797 | if (speed == 0) { | ||
1798 | LOG_INFO("XDS110: RTCK not supported"); | ||
1799 | return ERROR_JTAG_NOT_IMPLEMENTED; | ||
1800 | } | ||
1801 | |||
1802 | if (speed > XDS110_MAX_TCK_SPEED) { | ||
1803 | LOG_INFO("XDS110: reduce speed request: %dkHz to %dkHz maximum", | ||
1804 | speed, XDS110_MAX_TCK_SPEED); | ||
1805 | speed = XDS110_MAX_TCK_SPEED; | ||
1806 | } | ||
1807 | |||
1808 | if (speed < XDS110_MIN_TCK_SPEED) { | ||
1809 | LOG_INFO("XDS110: increase speed request: %dkHz to %dkHz minimum", | ||
1810 | speed, XDS110_MIN_TCK_SPEED); | ||
1811 | speed = XDS110_MIN_TCK_SPEED; | ||
1812 | } | ||
1813 | |||
1814 | /* The default is the maximum frequency the XDS110 can support */ | ||
1815 | uint32_t freq_to_use = XDS110_MAX_TCK_SPEED * 1000; /* Hz */ | ||
1816 | uint32_t delay_count = 0; | ||
1817 | |||
1818 | if (XDS110_MAX_TCK_SPEED != speed) { | ||
1819 | freq_to_use = speed * 1000; /* Hz */ | ||
1820 | |||
1821 | /* Calculate the delay count value */ | ||
1822 | double one_giga = 1000000000; | ||
1823 | /* Get the pulse duration for the maximum frequency supported in ns */ | ||
1824 | double max_freq_pulse_duration = one_giga / | ||
1825 | (XDS110_MAX_TCK_SPEED * 1000); | ||
1826 | |||
1827 | /* Convert frequency to pulse duration */ | ||
1828 | double freq_to_pulse_width_in_ns = one_giga / freq_to_use; | ||
1829 | |||
1830 | /* | ||
1831 | * Start with the pulse duration for the maximum frequency. Keep | ||
1832 | * decrementing the time added by each count value till the requested | ||
1833 | * frequency pulse is less than the calculated value. | ||
1834 | */ | ||
1835 | double current_value = max_freq_pulse_duration; | ||
1836 | |||
1837 | while (current_value < freq_to_pulse_width_in_ns) { | ||
1838 | current_value += XDS110_TCK_PULSE_INCREMENT; | ||
1839 | ++delay_count; | ||
1840 | } | ||
1841 | |||
1842 | /* | ||
1843 | * Determine which delay count yields the best match. | ||
1844 | * The one obtained above or one less. | ||
1845 | */ | ||
1846 | if (delay_count) { | ||
1847 | double diff_freq_1 = freq_to_use - | ||
1848 | (one_giga / (max_freq_pulse_duration + | ||
1849 | (XDS110_TCK_PULSE_INCREMENT * delay_count))); | ||
1850 | double diff_freq_2 = (one_giga / (max_freq_pulse_duration + | ||
1851 | (XDS110_TCK_PULSE_INCREMENT * (delay_count - 1)))) - | ||
1852 | freq_to_use; | ||
1853 | |||
1854 | /* One less count value yields a better match */ | ||
1855 | if (diff_freq_1 > diff_freq_2) | ||
1856 | --delay_count; | ||
1857 | } | ||
1858 | } | ||
1859 | |||
1860 | /* Send the delay count to the XDS110 firmware */ | ||
1861 | success = xds_set_tck_delay(delay_count); | ||
1862 | |||
1863 | if (success) { | ||
1864 | xds110.delay_count = delay_count; | ||
1865 | xds110.speed = speed; | ||
1866 | } | ||
1867 | |||
1868 | return (success) ? ERROR_OK : ERROR_FAIL; | ||
1869 | } | ||
1870 | |||
1871 | static int xds110_speed_div(int speed, int *khz) | ||
1872 | { | ||
1873 | *khz = speed; | ||
1874 | return ERROR_OK; | ||
1875 | } | ||
1876 | |||
1877 | static int xds110_khz(int khz, int *jtag_speed) | ||
1878 | { | ||
1879 | *jtag_speed = khz; | ||
1880 | return ERROR_OK; | ||
1881 | } | ||
1882 | |||
1883 | static int_least32_t xds110_swd_frequency(int_least32_t hz) | ||
1884 | { | ||
1885 | if (hz > 0) | ||
1886 | xds110_speed(hz / 1000); | ||
1887 | return hz; | ||
1888 | } | ||
1889 | |||
1890 | COMMAND_HANDLER(xds110_handle_info_command) | ||
1891 | { | ||
1892 | xds110_show_info(); | ||
1893 | return ERROR_OK; | ||
1894 | } | ||
1895 | |||
1896 | COMMAND_HANDLER(xds110_handle_serial_command) | ||
1897 | { | ||
1898 | wchar_t serial[XDS110_SERIAL_LEN + 1]; | ||
1899 | |||
1900 | xds110.serial[0] = 0; | ||
1901 | |||
1902 | if (CMD_ARGC == 1) { | ||
1903 | size_t len = mbstowcs(0, CMD_ARGV[0], 0); | ||
1904 | if (len > XDS110_SERIAL_LEN) { | ||
1905 | LOG_ERROR("XDS110: serial number is limited to %d characters", | ||
1906 | XDS110_SERIAL_LEN); | ||
1907 | return ERROR_FAIL; | ||
1908 | } | ||
1909 | if ((size_t)-1 == mbstowcs(serial, CMD_ARGV[0], len + 1)) { | ||
1910 | LOG_ERROR("XDS110: unable to convert serial number"); | ||
1911 | return ERROR_FAIL; | ||
1912 | } | ||
1913 | |||
1914 | for (uint32_t i = 0; i < len; i++) { | ||
1915 | xds110.serial[i] = (char)serial[i]; | ||
1916 | } | ||
1917 | xds110.serial[len] = 0; | ||
1918 | } else { | ||
1919 | LOG_ERROR("XDS110: expected exactly one argument to xds110_serial " | ||
1920 | "<serial-number>"); | ||
1921 | return ERROR_FAIL; | ||
1922 | } | ||
1923 | |||
1924 | return ERROR_OK; | ||
1925 | } | ||
1926 | |||
1927 | static const struct command_registration xds110_subcommand_handlers[] = { | ||
1928 | { | ||
1929 | .name = "info", | ||
1930 | .handler = &xds110_handle_info_command, | ||
1931 | .mode = COMMAND_EXEC, | ||
1932 | .usage = "", | ||
1933 | .help = "show XDS110 info", | ||
1934 | }, | ||
1935 | COMMAND_REGISTRATION_DONE | ||
1936 | }; | ||
1937 | |||
1938 | static const struct command_registration xds110_command_handlers[] = { | ||
1939 | { | ||
1940 | .name = "xds110", | ||
1941 | .mode = COMMAND_ANY, | ||
1942 | .help = "perform XDS110 management", | ||
1943 | .usage = "<cmd>", | ||
1944 | .chain = xds110_subcommand_handlers, | ||
1945 | }, | ||
1946 | { | ||
1947 | .name = "xds110_serial", | ||
1948 | .handler = &xds110_handle_serial_command, | ||
1949 | .mode = COMMAND_CONFIG, | ||
1950 | .help = "set the XDS110 probe serial number", | ||
1951 | .usage = "serial_string", | ||
1952 | }, | ||
1953 | COMMAND_REGISTRATION_DONE | ||
1954 | }; | ||
1955 | |||
1956 | static const struct swd_driver xds110_swd_driver = { | ||
1957 | .init = xds110_swd_init, | ||
1958 | .frequency = xds110_swd_frequency, | ||
1959 | .switch_seq = xds110_swd_switch_seq, | ||
1960 | .read_reg = xds110_swd_read_reg, | ||
1961 | .write_reg = xds110_swd_write_reg, | ||
1962 | .run = xds110_swd_run_queue, | ||
1963 | }; | ||
1964 | |||
1965 | static const char * const xds110_transport[] = { "swd", "jtag", NULL }; | ||
1966 | |||
1967 | struct jtag_interface xds110_interface = { | ||
1968 | .name = "xds110", | ||
1969 | .commands = xds110_command_handlers, | ||
1970 | .swd = &xds110_swd_driver, | ||
1971 | .transports = xds110_transport, | ||
1972 | |||
1973 | .execute_queue = xds110_execute_queue, | ||
1974 | .speed = xds110_speed, | ||
1975 | .speed_div = xds110_speed_div, | ||
1976 | .khz = xds110_khz, | ||
1977 | .init = xds110_init, | ||
1978 | .quit = xds110_quit, | ||
1979 | }; | ||
diff --git a/openocd/src/jtag/interfaces.c b/openocd/src/jtag/interfaces.c index ad656a8..1dc27f1 100644 --- a/openocd/src/jtag/interfaces.c +++ b/openocd/src/jtag/interfaces.c | |||
@@ -123,6 +123,9 @@ extern struct jtag_interface bcm2835gpio_interface; | |||
123 | #if BUILD_CMSIS_DAP == 1 | 123 | #if BUILD_CMSIS_DAP == 1 |
124 | extern struct jtag_interface cmsis_dap_interface; | 124 | extern struct jtag_interface cmsis_dap_interface; |
125 | #endif | 125 | #endif |
126 | #if BUILD_XDS110 == 1 | ||
127 | extern struct jtag_interface xds110_interface; | ||
128 | #endif | ||
126 | #endif /* standard drivers */ | 129 | #endif /* standard drivers */ |
127 | 130 | ||
128 | /** | 131 | /** |
@@ -216,6 +219,9 @@ struct jtag_interface *jtag_interfaces[] = { | |||
216 | #if BUILD_CMSIS_DAP == 1 | 219 | #if BUILD_CMSIS_DAP == 1 |
217 | &cmsis_dap_interface, | 220 | &cmsis_dap_interface, |
218 | #endif | 221 | #endif |
222 | #if BUILD_XDS110 == 1 | ||
223 | &xds110_interface, | ||
224 | #endif | ||
219 | #endif /* standard drivers */ | 225 | #endif /* standard drivers */ |
220 | NULL, | 226 | NULL, |
221 | }; | 227 | }; |
diff --git a/openocd/tcl/interface/xds110.cfg b/openocd/tcl/interface/xds110.cfg new file mode 100644 index 0000000..cabff55 --- /dev/null +++ b/openocd/tcl/interface/xds110.cfg | |||
@@ -0,0 +1,12 @@ | |||
1 | # | ||
2 | # Texas Instruments XDS110 | ||
3 | # | ||
4 | # http://processors.wiki.ti.com/index.php/XDS110 | ||
5 | # | ||
6 | |||
7 | interface xds110 | ||
8 | |||
9 | # Use serial number option to use a specific XDS110 | ||
10 | # when more than one are connected to the host. | ||
11 | #xds110_serial 00000000 | ||
12 | |||