From patchwork Fri Nov 3 19:52:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: auh@yoctoproject.org X-Patchwork-Id: 33954 Return-Path: Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B95D9C04A95 for ; Fri, 3 Nov 2023 19:53:08 +0000 (UTC) Received: from a27-23.smtp-out.us-west-2.amazonses.com (a27-23.smtp-out.us-west-2.amazonses.com [54.240.27.23]) by mx.groups.io with SMTP id smtpd.web10.63867.1699041165979797613 for ; Fri, 03 Nov 2023 12:52:56 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@yoctoproject.org header.s=lvjh2tk576v2ro5mi6k4dt3mc6wpqbky header.b=hrXOOEIQ; dkim=pass header.i=@amazonses.com header.s=hsbnp7p3ensaochzwyq5wwmceodymuwv header.b=rA9pxeCv; spf=pass (domain: us-west-2.amazonses.com, ip: 54.240.27.23, mailfrom: 0101018b96bee806-c64e7174-8dbd-41c6-848e-43e3abb36c98-000000@us-west-2.amazonses.com) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=lvjh2tk576v2ro5mi6k4dt3mc6wpqbky; d=yoctoproject.org; t=1699041176; h=Content-Type:MIME-Version:From:To:Cc:Subject:Message-Id:Date; bh=op/dj74Cl6ms5CT3Prv0S3zEQx1T+Xg3fG4A6ZOZs1M=; b=hrXOOEIQZLWAqDXmcngk8nqCNVcvJEljaN2sEn2DbECZ3Zj43wi/NPCgAa/2kNpz DPb+EkP5oQ1yVH1h8JtpJQCRgXBB9+rBuSwOJo+vSDdYPqs+2d1s7ZqZMKtwt3KABXP B3E4EUU0T2V/WhqclrQ2GPq0A53fvoPPhdxDA6DI= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=hsbnp7p3ensaochzwyq5wwmceodymuwv; d=amazonses.com; t=1699041176; h=Content-Type:MIME-Version:From:To:Cc:Subject:Message-Id:Date:Feedback-ID; bh=op/dj74Cl6ms5CT3Prv0S3zEQx1T+Xg3fG4A6ZOZs1M=; b=rA9pxeCvpnrRN6aZYIWIm2oLdjKleFV8eqry48FcLovIZl9atv2zYQK89EqSpv/8 yVM40pEjG+CnG18osqM+8+EdB2rmT79ZUNQQYkZE6jgZVdN4blutfFT5RlL3lpqggDR 13uklKIBrpjXpUp1su4ZxCRtPg9YadWlpNtxw0aI= MIME-Version: 1.0 From: auh@yoctoproject.org To: Forced@yoctoproject.org, maintainer@yoctoproject.org, for@yoctoproject.org, AUH@yoctoproject.org Cc: openembedded-devel@lists.openembedded.org Subject: [AUH] openocd: upgrading to 0.12.0 FAILED Message-ID: <0101018b96bee806-c64e7174-8dbd-41c6-848e-43e3abb36c98-000000@us-west-2.amazonses.com> Date: Fri, 3 Nov 2023 19:52:55 +0000 Feedback-ID: 1.us-west-2.9np3MYPs3fEaOBysGKSlUD4KtcmPijcmS9Az2Hwf7iQ=:AmazonSES X-SES-Outgoing: 2023.11.03-54.240.27.23 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 03 Nov 2023 19:53:08 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/106032 Hello, this email is a notification from the Auto Upgrade Helper that the automatic attempt to upgrade the recipe *openocd* to *0.12.0* has Failed(do_compile). Detailed error information: do_compile failed Next steps: - apply the patch: git am 0001-openocd-upgrade-0.12-0.12.0.patch - check the changes to upstream patches and summarize them in the commit message, - compile an image that contains the package - perform some basic sanity tests - amend the patch and sign it off: git commit -s --reset-author --amend - send it to the appropriate mailing list Alternatively, if you believe the recipe should not be upgraded at this time, you can fill RECIPE_NO_UPDATE_REASON in respective recipe file so that automatic upgrades would no longer be attempted. Please review the attached files for further information and build/update failures. Any problem please file a bug at https://bugzilla.yoctoproject.org/enter_bug.cgi?product=Automated%20Update%20Handler Regards, The Upgrade Helper -- >8 -- From 5701927d6fe08949ba5f9d78a4788065e9cda4b0 Mon Sep 17 00:00:00 2001 From: Upgrade Helper Date: Fri, 3 Nov 2023 17:30:30 +0000 Subject: [PATCH] openocd: upgrade 0.12 -> 0.12.0 --- ...001-Restore-normal-development-cycle.patch | 296 + ...2-Deprecate-libjaylink-Git-submodule.patch | 67 + ...it-together-with-aice-adapter-driver.patch | 19095 ++++++++++++++++ ...t-workarounds-for-expr-syntax-change.patch | 127 + ...lash-nor-avrf-add-ATmega32U4-support.patch | 66 + ...move-needless-target_was_examined-ch.patch | 31 + ...i-Add-issi-is25lq040b-to-device-list.patch | 30 + ...pport-per-build-configuration-specif.patch | 1295 ++ ...dd-support-of-pointer-authentication.patch | 460 + ...heck-error-in-armv7m_restore_context.patch | 34 + ...ortex_m-add-SMP-support-for-Cortex-M.patch | 400 + ...-make-SPI-flash-ID-detection-optiona.patch | 103 + ...cl-target-add-SMP-mode-to-rp2040.cfg.patch | 51 + ...4-tcl-target-remove-rp2040-core0.cfg.patch | 83 + ...recated-command-riscv-set_prefer_sba.patch | 71 + ...cated-command-riscv-test_sba_config_.patch | 480 + ...Improve-three-adapter-related-prints.patch | 66 + ...-stm32l4x-avoid-multiple-assignments.patch | 29 + ...19-target-armv7m-Rename-xPSR-to-xpsr.patch | 34 + ...h-nor-numicro-reorder-the-parts-list.patch | 1395 ++ ...pport-Nuvoton-M541-NUC442-472-series.patch | 649 + ...uration-file-for-Nuvoton-M541-NUC442.patch | 101 + ...b-loaders-move-numicro-M4-write-asse.patch | 216 + ...b-loaders-move-numicro-M0-write-asse.patch | 222 + ...-add-container-for-lsusb-dump-of-ada.patch | 103 + ...pters-add-lsusb-dump-of-few-adapters.patch | 2773 +++ ...-doc-usb_adapters-add-other-adapters.patch | 1326 ++ ...d-disassembler-helper-for-files-.inc.patch | 80 + ...-cmsis_dap-move-pending-request-FIFO.patch | 269 + ...is_dap-use-dap-parameter-instead-of-.patch | 68 + ...drivers-cmsis_dap-use-unsigned-types.patch | 179 + ...sis_dap-introduce-packet_usable_size.patch | 104 + ...msis_dap-improve-USB-packets-filling.patch | 180 + ...is_dap-speed-up-long-transfers-using.patch | 239 + ...is_dap-prevent-conn-discon-workaroun.patch | 34 + ...0036-tcl-target-enable-rtos-hwthread.patch | 84 + ...4x-Add-revision-X-and-C-for-STM32U57.patch | 27 + ...Add-.cache-and-compile_commands.json.patch | 43 + ...-parse-command-options-in-swd-newdap.patch | 49 + ...eric-helper-for-commands-jtag-newtap.patch | 270 + ...drop-jtag_poll_mask-from-flash-write.patch | 40 + ...generic-little-endian-CRC32-function.patch | 216 + ...Allow-overriding-the-flash-bank-size.patch | 44 + ...ink-to-IgnoreHardwareSerialNumber-in.patch | 30 + ...pters-add-lsusb-dump-of-esp_usb_jtag.patch | 185 + ...stacking-info-to-the-new-nuttx-stack.patch | 204 + ...7-rtos-nuttx-add-riscv-stacking-info.patch | 89 + ...-rtos-add-custom-stack-read-function.patch | 52 + ...tacking-info-for-Espressif-Xtensa-ch.patch | 382 + .../openocd/0050-rtos-Support-rt-kernel.patch | 473 + ...os-Fix-constness-of-struct-rtos_type.patch | 168 + ...njtag-fix-annoying-num_cycles-16-war.patch | 51 + ...bang-avoid-mostly-harmless-glitch-on.patch | 68 + ...m2835gpio-use-rounding-in-delay-math.patch | 50 + ...2835gpio-refactor-delays-to-inline-f.patch | 63 + ...iversal-config-for-all-Raspberry-Pi-.patch | 242 + ...ig.h-includes-from-stackings-headers.patch | 237 + ...ag-drivers-jlink-allow-SWD-multidrop.patch | 60 + ...get-add-rescue-mode-to-RP2040-config.patch | 71 + ...sh-nor-spi-Add-some-zbit-flash-chips.patch | 50 + ...te-command-arc-jtag-get-aux-reg-as-C.patch | 81 + ...te-command-arc-jtag-set-aux-reg-as-C.patch | 78 + ...te-command-arc-jtag-get-core-reg-as-.patch | 89 + ...te-command-arc-jtag-set-core-reg-as-.patch | 84 + ...te-command-arc-get-reg-field-as-COMM.patch | 116 + ...te-command-arc-num-actionpoints-as-C.patch | 105 + ...rror-handling-in-command-arc-set-reg.patch | 40 + ...068-helper-nvp-add-openocd-nvp-files.patch | 205 + ...te-command-arc-add-reg-type-flags-as.patch | 293 + ...te-command-arc-add-reg-type-struct-a.patch | 345 + ...te-command-arc-add-reg-as-COMMAND_HA.patch | 334 + ...4x-Add-revision-Z-for-STM32L552-562-.patch | 28 + ...atement-about-libjaylink-Git-submodu.patch | 28 + ...evices-continuation-code-for-manufac.patch | 156 + ...lash-nor-spi-add-25pe-10-20-40-80-16.patch | 31 + ...rop-last-LF-n-from-sequence-of-comma.patch | 83 + ...is_dap-run-queue-on-reaching-transac.patch | 47 + ...es-fix-source-of-raspberrypi-gpio-co.patch | 27 + ...at91sam9g20-ek-remove-outdated-FIXME.patch | 31 + ...DO-remove-outdated-AT91SAM92xx-entry.patch | 31 + ...elper-allow-external-use-of-jtag_lib.patch | 45 + ...vent-misleading-error-msg-when-more-.patch | 111 + ...-at91samd-fix-RAM-size-for-SAMR34-35.patch | 31 + ...md-add-missing-SAMR34-35-part-number.patch | 32 + ...0085-doc-add-missing-FreeRTOS-symbol.patch | 31 + ...o-initialize-ELF-segments-up-to-p_me.patch | 166 + .../0087-target-xtensa-add-NX-support.patch | 806 + ...ler.h-to-handle-compiler-specific-wo.patch | 111 + ...0089-openocd-drop-JIM_EMBEDDED-macro.patch | 35 + .../0090-build-fix-distcheck-for-jimtcl.patch | 81 + .../0091-jimtcl-update-to-version-0.82.patch | 53 + ...ols-test_cpu_speed-Fix-register-name.patch | 30 + ...-exec-permission-to-tcl-config-files.patch | 28 + ...d-line-options-noreset-and-addcycles.patch | 145 + ...5-helper-compiler-fix-build-on-MacOS.patch | 41 + ...spressif-target-support-and-refactor.patch | 758 + ...-check-common_magic-instead-of-gdb_a.patch | 42 + ...d-update-comment-about-SWD-capabilit.patch | 29 + ...ag-fix-endianness-error-in-transacti.patch | 46 + ...0100-svf-fix-leaking-file-descriptor.patch | 54 + ...eak-on-error-during-command-executio.patch | 68 + ...f-make-command-svf-syntax-consistent.patch | 218 + ...ewrite-command-ocd_find-as-COMMAND_H.patch | 62 + ...e-command-transport-select-as-COMMAN.patch | 149 + ...e-command-flash-list-as-COMMAND_HAND.patch | 95 + ...ewrite-command-ms-as-COMMAND_HANDLER.patch | 55 + ...e-command-version-as-COMMAND_HANDLER.patch | 89 + ...and-rtt-channellist-as-COMMAND_HANDL.patch | 158 + ...ewrite-commands-aarch64-mcr-mrc-as-C.patch | 224 + ...ewrite-commands-arm-mcr-mrc-as-COMMA.patch | 222 + ...te-command-cti-names-as-COMMAND_HAND.patch | 58 + ...mand-adapter-name-as-COMMAND_HANDLER.patch | 62 + ...ommand-jtag-names-as-COMMAND_HANDLER.patch | 65 + ...mand-jtag-arp_init-as-COMMAND_HANDLE.patch | 60 + ...mand-jtag-arp_init-reset-as-COMMAND_.patch | 70 + ...mmand-flush_count-as-COMMAND_HANDLER.patch | 53 + ...ewrite-command-dap-names-as-COMMAND_.patch | 58 + ...swo-rewrite-command-tpiu-disable-as-.patch | 76 + ...swo-rewrite-command-tpiu-enable-as-C.patch | 233 + ...swo-rewrite-command-tpiu-names-as-CO.patch | 59 + ...swo-rewrite-command-tpiu-init-as-COM.patch | 58 + ...ommand-read_memory-as-COMMAND_HANDLE.patch | 212 + ...ommand-target-curstate-as-COMMAND_HA.patch | 60 + ...ommand-was_examined-as-COMMAND_HANDL.patch | 53 + ...ommand-examine_deferred-as-COMMAND_H.patch | 53 + ...ommand-arp_halt_gdb-as-COMMAND_HANDL.patch | 56 + ...ommand-target-current-as-COMMAND_HAN.patch | 57 + ...ommand-target-types-as-COMMAND_HANDL.patch | 59 + ...ommand-target-names-as-COMMAND_HANDL.patch | 59 + ...ommand-target-smp-as-COMMAND_HANDLER.patch | 121 + ...usb-a9260-fix-and-refactor-broken-su.patch | 126 + .../0132-tcl-board-add-Calao-USB-A9G20.patch | 37 + .../0133-flash-nor-missing-fileio_close.patch | 28 + ...increase-delete-tag-and-release-vers.patch | 67 + ...orkflow-build-libjaylink-from-source.patch | 96 + ...me-optimization-of-freertos_update_t.patch | 51 + ...m4k-fix-condition-on-overlapping-wor.patch | 38 + ...target-mips_m4k-add-fast-read-method.patch | 119 + ...139-helper-list-remove-unused-hlist_.patch | 285 + ...t-re-align-with-Linux-kernel-6.3-rc1.patch | 145 + .../openocd/0141-ipdbg-whitespaces.patch | 100 + ...compiler-fix-build-with-gcc-on-MacOS.patch | 40 + ...3-tcl-zynq_7000-add-missing-id-codes.patch | 59 + ...xc7-remove-virtex-7-devices-with-ir-.patch | 51 + ...-doc-drop-resume-will-wait-5-seconds.patch | 36 + ...-add-application-tracing-functionali.patch | 2250 ++ ...c-server-Fix-memory-leak-of-reg_list.patch | 28 + ....c-Fix-Linux-user-space-border-check.patch | 29 + .../openocd/0149-flash-rsl10-fix-typo.patch | 27 + ...pld-move-file-sanity-checks-to-pld.c.patch | 90 + ...151-Committing-changes-from-do_patch.patch | 24 + .../recipes-devtools/openocd/openocd_git.bb | 165 +- 152 files changed, 45717 insertions(+), 7 deletions(-) create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0001-Restore-normal-development-cycle.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0002-Deprecate-libjaylink-Git-submodule.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0003-nds32-drop-it-together-with-aice-adapter-driver.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0004-openocd-revert-workarounds-for-expr-syntax-change.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0005-flash-nor-avrf-add-ATmega32U4-support.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0006-target-xtensa-remove-needless-target_was_examined-ch.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0007-flash-nor-spi-Add-issi-is25lq040b-to-device-list.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0008-src-rtos-eCos-Support-per-build-configuration-specif.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0009-armv8-Add-support-of-pointer-authentication.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0010-target-armv7m-check-error-in-armv7m_restore_context.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0011-target-cortex_m-add-SMP-support-for-Cortex-M.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0012-flash-nor-rp2040-make-SPI-flash-ID-detection-optiona.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0013-tcl-target-add-SMP-mode-to-rp2040.cfg.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0014-tcl-target-remove-rp2040-core0.cfg.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0015-riscv-drop-deprecated-command-riscv-set_prefer_sba.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0016-riscv-drop-deprecated-command-riscv-test_sba_config_.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0017-adapter-Improve-three-adapter-related-prints.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0018-flash-stm32l4x-avoid-multiple-assignments.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0019-target-armv7m-Rename-xPSR-to-xpsr.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0020-flash-nor-numicro-reorder-the-parts-list.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0021-flash-support-Nuvoton-M541-NUC442-472-series.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0022-tcl-add-a-configuration-file-for-Nuvoton-M541-NUC442.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0023-flash-nor-contrib-loaders-move-numicro-M4-write-asse.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0024-flash-nor-contrib-loaders-move-numicro-M0-write-asse.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0025-doc-usb_adapters-add-container-for-lsusb-dump-of-ada.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0026-doc-usb_adapters-add-lsusb-dump-of-few-adapters.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0027-doc-usb_adapters-add-other-adapters.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0028-tools-add-disassembler-helper-for-files-.inc.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0029-jtag-drivers-cmsis_dap-move-pending-request-FIFO.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0030-jtag-drivers-cmsis_dap-use-dap-parameter-instead-of-.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0031-jtag-drivers-cmsis_dap-use-unsigned-types.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0032-jtag-drivers-cmsis_dap-introduce-packet_usable_size.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0033-jtag-drivers-cmsis_dap-improve-USB-packets-filling.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0034-jtag-drivers-cmsis_dap-speed-up-long-transfers-using.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0035-jtag-drivers-cmsis_dap-prevent-conn-discon-workaroun.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0036-tcl-target-enable-rtos-hwthread.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0037-flash-nor-stm32l4x-Add-revision-X-and-C-for-STM32U57.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0038-.gitignore-Add-.cache-and-compile_commands.json.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0039-jtag-parse-command-options-in-swd-newdap.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0040-jtag-hla-use-generic-helper-for-commands-jtag-newtap.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0041-flash-nor-psoc4-drop-jtag_poll_mask-from-flash-write.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0042-helper-Add-generic-little-endian-CRC32-function.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0043-stm32f3x-Allow-overriding-the-flash-bank-size.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0044-doc-fix-broken-link-to-IgnoreHardwareSerialNumber-in.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0045-doc-usb_adapters-add-lsusb-dump-of-esp_usb_jtag.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0046-rtos-nuttx-move-stacking-info-to-the-new-nuttx-stack.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0047-rtos-nuttx-add-riscv-stacking-info.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0048-rtos-add-custom-stack-read-function.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0049-rtos-nuttx-add-stacking-info-for-Espressif-Xtensa-ch.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0050-rtos-Support-rt-kernel.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0051-rtos-Fix-constness-of-struct-rtos_type.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0052-jtag-drivers-openjtag-fix-annoying-num_cycles-16-war.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0053-jtag-drivers-bitbang-avoid-mostly-harmless-glitch-on.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0054-jtag-drivers-bcm2835gpio-use-rounding-in-delay-math.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0055-jtag-drivers-bcm2835gpio-refactor-delays-to-inline-f.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0056-tcl-interface-universal-config-for-all-Raspberry-Pi-.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0057-rtos-remove-config.h-includes-from-stackings-headers.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0058-jtag-drivers-jlink-allow-SWD-multidrop.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0059-tcl-target-add-rescue-mode-to-RP2040-config.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0060-flash-nor-spi-Add-some-zbit-flash-chips.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0061-target-arc-rewrite-command-arc-jtag-get-aux-reg-as-C.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0062-target-arc-rewrite-command-arc-jtag-set-aux-reg-as-C.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0063-target-arc-rewrite-command-arc-jtag-get-core-reg-as-.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0064-target-arc-rewrite-command-arc-jtag-set-core-reg-as-.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0065-target-arc-rewrite-command-arc-get-reg-field-as-COMM.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0066-target-arc-rewrite-command-arc-num-actionpoints-as-C.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0067-target-arc-fix-error-handling-in-command-arc-set-reg.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0068-helper-nvp-add-openocd-nvp-files.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0069-target-arc-rewrite-command-arc-add-reg-type-flags-as.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0070-target-arc-rewrite-command-arc-add-reg-type-struct-a.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0071-target-arc-rewrite-command-arc-add-reg-as-COMMAND_HA.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0072-flash-nor-stm32l4x-Add-revision-Z-for-STM32L552-562-.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0073-README-Remove-statement-about-libjaylink-Git-submodu.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0074-new-SPI-memory-devices-continuation-code-for-manufac.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0075-flash-nor-spi-add-25pe-10-20-40-80-16.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0076-helper-command-drop-last-LF-n-from-sequence-of-comma.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0077-jtag-drivers-cmsis_dap-run-queue-on-reaching-transac.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0078-tlc-interface-does-fix-source-of-raspberrypi-gpio-co.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0079-tcl-board-at91sam9g20-ek-remove-outdated-FIXME.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0080-TODO-remove-outdated-AT91SAM92xx-entry.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0081-drivers-libusb_helper-allow-external-use-of-jtag_lib.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0082-drivers-ftdi-prevent-misleading-error-msg-when-more-.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0083-flash-nor-at91samd-fix-RAM-size-for-SAMR34-35.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0084-flash-nor-at91samd-add-missing-SAMR34-35-part-number.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0085-doc-add-missing-FreeRTOS-symbol.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0086-target-image-zero-initialize-ELF-segments-up-to-p_me.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0087-target-xtensa-add-NX-support.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0088-helper-add-compiler.h-to-handle-compiler-specific-wo.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0089-openocd-drop-JIM_EMBEDDED-macro.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0090-build-fix-distcheck-for-jimtcl.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0091-jimtcl-update-to-version-0.82.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0092-tcl-tools-test_cpu_speed-Fix-register-name.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0093-tcl-remove-exec-permission-to-tcl-config-files.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0094-svf-new-command-line-options-noreset-and-addcycles.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0095-helper-compiler-fix-build-on-MacOS.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0096-rtos-nuttx-add-Espressif-target-support-and-refactor.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0097-target-espressif-check-common_magic-instead-of-gdb_a.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0098-target-adi_v5_swd-update-comment-about-SWD-capabilit.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0099-target-adi_v5_jtag-fix-endianness-error-in-transacti.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0100-svf-fix-leaking-file-descriptor.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0101-svf-fix-memory-leak-on-error-during-command-executio.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0102-svf-make-command-svf-syntax-consistent.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0103-helper-command-rewrite-command-ocd_find-as-COMMAND_H.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0104-transport-rewrite-command-transport-select-as-COMMAN.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0105-flash-nor-rewrite-command-flash-list-as-COMMAND_HAND.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0106-helper-util-rewrite-command-ms-as-COMMAND_HANDLER.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0107-openocd-rewrite-command-version-as-COMMAND_HANDLER.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0108-rtt-rewrite-command-rtt-channellist-as-COMMAND_HANDL.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0109-target-aarch64-rewrite-commands-aarch64-mcr-mrc-as-C.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0110-target-armv4_5-rewrite-commands-arm-mcr-mrc-as-COMMA.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0111-target-cti-rewrite-command-cti-names-as-COMMAND_HAND.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0112-jtag-rewrite-command-adapter-name-as-COMMAND_HANDLER.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0113-jtag-rewrite-command-jtag-names-as-COMMAND_HANDLER.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0114-jtag-rewrite-command-jtag-arp_init-as-COMMAND_HANDLE.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0115-jtag-rewrite-command-jtag-arp_init-reset-as-COMMAND_.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0116-jtag-rewrite-command-flush_count-as-COMMAND_HANDLER.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0117-target-arm_dap-rewrite-command-dap-names-as-COMMAND_.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0118-target-arm_tpiu_swo-rewrite-command-tpiu-disable-as-.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0119-target-arm_tpiu_swo-rewrite-command-tpiu-enable-as-C.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0120-target-arm_tpiu_swo-rewrite-command-tpiu-names-as-CO.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0121-target-arm_tpiu_swo-rewrite-command-tpiu-init-as-COM.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0122-target-rewrite-command-read_memory-as-COMMAND_HANDLE.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0123-target-rewrite-command-target-curstate-as-COMMAND_HA.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0124-target-rewrite-command-was_examined-as-COMMAND_HANDL.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0125-target-rewrite-command-examine_deferred-as-COMMAND_H.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0126-target-rewrite-command-arp_halt_gdb-as-COMMAND_HANDL.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0127-target-rewrite-command-target-current-as-COMMAND_HAN.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0128-target-rewrite-command-target-types-as-COMMAND_HANDL.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0129-target-rewrite-command-target-names-as-COMMAND_HANDL.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0130-target-rewrite-command-target-smp-as-COMMAND_HANDLER.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0131-tcl-board-calao-usb-a9260-fix-and-refactor-broken-su.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0132-tcl-board-add-Calao-USB-A9G20.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0133-flash-nor-missing-fileio_close.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0134-github-workflow-increase-delete-tag-and-release-vers.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0135-github-workflow-build-libjaylink-from-source.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0136-rtos-FreeRTOS-some-optimization-of-freertos_update_t.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0137-src-target-mips_m4k-fix-condition-on-overlapping-wor.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0138-src-target-mips_m4k-add-fast-read-method.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0139-helper-list-remove-unused-hlist_.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0140-helper-list-re-align-with-Linux-kernel-6.3-rc1.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0141-ipdbg-whitespaces.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0142-helper-compiler-fix-build-with-gcc-on-MacOS.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0143-tcl-zynq_7000-add-missing-id-codes.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0144-tcl-cpld-xilinx-xc7-remove-virtex-7-devices-with-ir-.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0145-doc-drop-resume-will-wait-5-seconds.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0146-target-espressif-add-application-tracing-functionali.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0147-src-server-Fix-memory-leak-of-reg_list.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0148-rtos-linux.c-Fix-Linux-user-space-border-check.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0149-flash-rsl10-fix-typo.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0150-pld-move-file-sanity-checks-to-pld.c.patch create mode 100644 meta-oe/recipes-devtools/openocd/openocd/0151-Committing-changes-from-do_patch.patch diff --git a/meta-oe/recipes-devtools/openocd/openocd/0001-Restore-normal-development-cycle.patch b/meta-oe/recipes-devtools/openocd/openocd/0001-Restore-normal-development-cycle.patch new file mode 100644 index 000000000..91a724b11 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0001-Restore-normal-development-cycle.patch @@ -0,0 +1,296 @@ +From f8a6553e82919bcfd37436dd6b95e99bb261d04c Mon Sep 17 00:00:00 2001 +From: Paul Fertser +Date: Sun, 15 Jan 2023 02:33:06 +0300 +Subject: [PATCH] Restore normal development cycle + +Signed-off-by: Paul Fertser +--- + NEWS | 99 +------------------------------------- + NEWS-0.12.0 | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++ + configure.ac | 2 +- + 3 files changed, 134 insertions(+), 99 deletions(-) + create mode 100644 NEWS-0.12.0 + +diff --git a/NEWS b/NEWS +index 208146a46..9db6c5fee 100644 +--- a/NEWS ++++ b/NEWS +@@ -2,126 +2,29 @@ This file includes highlights of the changes made in the OpenOCD + source archive release. + + JTAG Layer: +- * add default to adapter speed when unspecified (100 kHz) +- * AM335X gpio (BeagleBones) adapter driver +- * BCM2835 support for SWD +- * Cadence Virtual Debug (vdebug) adapter driver +- * CMSIS-DAP support for SWO and SWD multidrop +- * Espressif USB JTAG Programmer adapter driver +- * Remote bitbang support for Windows host +- * ST-LINK add TCP server support to adapter driver +- * SWD multidrop support + + Boundary Scan: + + Target Layer: +- * aarch64: support watchpoints +- * arm: support independent TPIU and SWO for trace +- * arm adi v5: support Large Physical Address Extension +- * arm adi v6: support added, for jtag and swd transport +- * cortex_a: support watchpoints +- * elf 64bit load support +- * Espressif: support ESP32, ESP32-S2 and ESP32-S3 cores +- * semihosting: support user defined operations +- * Xtensa: support Xtensa LX architecture via JTAG and ADIv5 DAP + + Flash Layer: +- * Atmel/Microchip SAM E51G18A, E51G19A, R35J18B, LAN9255 support +- * GigaDevice GD32E23x, GD32F1x0/3x0, GD32VF103 support +- * Nuvoton NPCX series support +- * onsemi RSL10 support +- * Raspberry Pi Pico RP2040 support +- * ST BlueNRG-LPS support +- * ST STM32 G05x, G06x, G0Bx, G0Cx, U57x, U58x, WB1x, WL5x support +- * ST STM32 G0, G4, L4, L4+, L5, WB, WL OTP support + + Board, Target, and Interface Configuration Scripts: +- * Ampere Computing eMAG8180, Altra ("Quicksilver") and Altra Max ("Mystique") board config +- * Cadence KC705 FPGA (Xtensa Development Platform) via JTAG and ADIv5 DAP board config +- * Digilent Nexys Video board config +- * Espressif ESP32 ETHERNET-KIT and WROVER-KIT board config +- * Espressif ESP32 via ESP USB Bridge generic board config +- * Espressif ESP32-S2 Kaluga 1 board config +- * Espressif ESP32-S2 with ESP USB Bridge board config +- * Espressif ESP32-S3 example board config +- * Kontron SMARC-sAL28 board config +- * LambdaConcept ECPIX-5 board config +- * Microchip ATSAMA5D27-SOM1-EK1 board config +- * Microchip EVB-LAN9255 board config +- * Microchip SAME51 Curiosity Nano board config +- * NXP FRDM-K64F, LS1046ARDB and LS1088ARDB board config +- * NXP RT6XX board config +- * Olimex H405 board config +- * Radiona ULX3S board config +- * Raspberry Pi 3 and Raspberry Pi 4 model B board config +- * Raspberry Pi Pico-Debug board config +- * Renesas R-Car V3U Falcon board config +- * ST BlueNRG-LPS steval-idb012v1 board config +- * ST NUCLEO-8S208RB board config +- * ST NUCLEO-G031K8, NUCLEO-G070RB, NUCLEO-G071RB board config +- * ST NUCLEO-G431KB, NUCLEO-G431RB, NUCLEO-G474RE board config +- * ST STM32MP13x-DK board config +- * TI AM625 EVM, AM642 EVM and AM654 EVM board config +- * TI J721E EVM, J721S2 EVM and J7200 EVM board config +- * Ampere Computing eMAG, Altra ("Quicksilver") and Altra Max ("Mystique") target config +- * Cadence Xtensa generic and Xtensa VDebug target config +- * Broadcom BCM2711, BCM2835, BCM2836 and BCM2837 target config +- * Espressif ESP32, ESP32-S2 and ESP32-S3 target config +- * Microchip ATSAMA5D2 series target config +- * NanoXplore NG-Ultra SoC target config +- * NXP IMX8QM target config +- * NXP LS1028A, LS1046A and LS1088A target config +- * NXP RT600 (Xtensa HiFi DSP) target config +- * onsemi RSL10 target config +- * Raspberry Pi Pico RP2040 target config +- * Renesas R8A779A0 V3U target config +- * Renesas RZ/Five target config +- * Renesas RZ/G2 MPU family target config +- * Rockchip RK3399 target config +- * ST BlueNRG-LPS target config +- * ST STM32MP13x target config +- * TI AM625, AM654, J721E and J721S2 target config +- * Ashling Opella-LD interface config +- * Aspeed AST2600 linuxgpiod based interface config +- * Blinkinlabs JTAG_Hat interface config +- * Cadence Virtual Debug (vdebug) interface config +- * Espressif ESP32-S2 Kaluga 1 board's interface config +- * Espressif USB Bridge jtag interface config +- * Infineon DAP miniWiggler V3 interface config +- * PLS SPC5 interface config +- * Tigard interface config +- * Lattice MachXO3 family FPGA config + + Server Layer: +- * GDB: add per-target remote protocol extensions +- * GDB: more 'Z' packets support +- * IPDBG JtagHost server functionality +- * semihosting: I/O redirection to TCP server +- * telnet: support for command's autocomplete + + RTOS: +- * 'none' rtos support +- * Zephyr rtos support + + Documentation: + + Build and Release: +- * Add json extension to jimtcl build +- * Drop dependency from libusb0 +- * Drop repository repo.or.cz for submodules +- * Move gerrit to https://review.openocd.org/ +- * Require autoconf 2.69 or newer +- * Update jep106 to revision JEP106BF.01 +- * Update jimtcl to version 0.81 +- * Update libjaylink to version 0.3.1 +- * New configure flag '--enable-jimtcl-maintainer' for jimtcl build + + + This release also contains a number of other important functional and + cosmetic bugfixes. For more details about what has changed since the + last release, see the git repository history: + +-http://sourceforge.net/p/openocd/code/ci/v0.12.0/log/?path= ++http://sourceforge.net/p/openocd/code/ci/v0.x.0/log/?path= + + + For older NEWS, see the NEWS files associated with each release +diff --git a/NEWS-0.12.0 b/NEWS-0.12.0 +new file mode 100644 +index 000000000..208146a46 +--- /dev/null ++++ b/NEWS-0.12.0 +@@ -0,0 +1,132 @@ ++This file includes highlights of the changes made in the OpenOCD ++source archive release. ++ ++JTAG Layer: ++ * add default to adapter speed when unspecified (100 kHz) ++ * AM335X gpio (BeagleBones) adapter driver ++ * BCM2835 support for SWD ++ * Cadence Virtual Debug (vdebug) adapter driver ++ * CMSIS-DAP support for SWO and SWD multidrop ++ * Espressif USB JTAG Programmer adapter driver ++ * Remote bitbang support for Windows host ++ * ST-LINK add TCP server support to adapter driver ++ * SWD multidrop support ++ ++Boundary Scan: ++ ++Target Layer: ++ * aarch64: support watchpoints ++ * arm: support independent TPIU and SWO for trace ++ * arm adi v5: support Large Physical Address Extension ++ * arm adi v6: support added, for jtag and swd transport ++ * cortex_a: support watchpoints ++ * elf 64bit load support ++ * Espressif: support ESP32, ESP32-S2 and ESP32-S3 cores ++ * semihosting: support user defined operations ++ * Xtensa: support Xtensa LX architecture via JTAG and ADIv5 DAP ++ ++Flash Layer: ++ * Atmel/Microchip SAM E51G18A, E51G19A, R35J18B, LAN9255 support ++ * GigaDevice GD32E23x, GD32F1x0/3x0, GD32VF103 support ++ * Nuvoton NPCX series support ++ * onsemi RSL10 support ++ * Raspberry Pi Pico RP2040 support ++ * ST BlueNRG-LPS support ++ * ST STM32 G05x, G06x, G0Bx, G0Cx, U57x, U58x, WB1x, WL5x support ++ * ST STM32 G0, G4, L4, L4+, L5, WB, WL OTP support ++ ++Board, Target, and Interface Configuration Scripts: ++ * Ampere Computing eMAG8180, Altra ("Quicksilver") and Altra Max ("Mystique") board config ++ * Cadence KC705 FPGA (Xtensa Development Platform) via JTAG and ADIv5 DAP board config ++ * Digilent Nexys Video board config ++ * Espressif ESP32 ETHERNET-KIT and WROVER-KIT board config ++ * Espressif ESP32 via ESP USB Bridge generic board config ++ * Espressif ESP32-S2 Kaluga 1 board config ++ * Espressif ESP32-S2 with ESP USB Bridge board config ++ * Espressif ESP32-S3 example board config ++ * Kontron SMARC-sAL28 board config ++ * LambdaConcept ECPIX-5 board config ++ * Microchip ATSAMA5D27-SOM1-EK1 board config ++ * Microchip EVB-LAN9255 board config ++ * Microchip SAME51 Curiosity Nano board config ++ * NXP FRDM-K64F, LS1046ARDB and LS1088ARDB board config ++ * NXP RT6XX board config ++ * Olimex H405 board config ++ * Radiona ULX3S board config ++ * Raspberry Pi 3 and Raspberry Pi 4 model B board config ++ * Raspberry Pi Pico-Debug board config ++ * Renesas R-Car V3U Falcon board config ++ * ST BlueNRG-LPS steval-idb012v1 board config ++ * ST NUCLEO-8S208RB board config ++ * ST NUCLEO-G031K8, NUCLEO-G070RB, NUCLEO-G071RB board config ++ * ST NUCLEO-G431KB, NUCLEO-G431RB, NUCLEO-G474RE board config ++ * ST STM32MP13x-DK board config ++ * TI AM625 EVM, AM642 EVM and AM654 EVM board config ++ * TI J721E EVM, J721S2 EVM and J7200 EVM board config ++ * Ampere Computing eMAG, Altra ("Quicksilver") and Altra Max ("Mystique") target config ++ * Cadence Xtensa generic and Xtensa VDebug target config ++ * Broadcom BCM2711, BCM2835, BCM2836 and BCM2837 target config ++ * Espressif ESP32, ESP32-S2 and ESP32-S3 target config ++ * Microchip ATSAMA5D2 series target config ++ * NanoXplore NG-Ultra SoC target config ++ * NXP IMX8QM target config ++ * NXP LS1028A, LS1046A and LS1088A target config ++ * NXP RT600 (Xtensa HiFi DSP) target config ++ * onsemi RSL10 target config ++ * Raspberry Pi Pico RP2040 target config ++ * Renesas R8A779A0 V3U target config ++ * Renesas RZ/Five target config ++ * Renesas RZ/G2 MPU family target config ++ * Rockchip RK3399 target config ++ * ST BlueNRG-LPS target config ++ * ST STM32MP13x target config ++ * TI AM625, AM654, J721E and J721S2 target config ++ * Ashling Opella-LD interface config ++ * Aspeed AST2600 linuxgpiod based interface config ++ * Blinkinlabs JTAG_Hat interface config ++ * Cadence Virtual Debug (vdebug) interface config ++ * Espressif ESP32-S2 Kaluga 1 board's interface config ++ * Espressif USB Bridge jtag interface config ++ * Infineon DAP miniWiggler V3 interface config ++ * PLS SPC5 interface config ++ * Tigard interface config ++ * Lattice MachXO3 family FPGA config ++ ++Server Layer: ++ * GDB: add per-target remote protocol extensions ++ * GDB: more 'Z' packets support ++ * IPDBG JtagHost server functionality ++ * semihosting: I/O redirection to TCP server ++ * telnet: support for command's autocomplete ++ ++RTOS: ++ * 'none' rtos support ++ * Zephyr rtos support ++ ++Documentation: ++ ++Build and Release: ++ * Add json extension to jimtcl build ++ * Drop dependency from libusb0 ++ * Drop repository repo.or.cz for submodules ++ * Move gerrit to https://review.openocd.org/ ++ * Require autoconf 2.69 or newer ++ * Update jep106 to revision JEP106BF.01 ++ * Update jimtcl to version 0.81 ++ * Update libjaylink to version 0.3.1 ++ * New configure flag '--enable-jimtcl-maintainer' for jimtcl build ++ ++ ++This release also contains a number of other important functional and ++cosmetic bugfixes. For more details about what has changed since the ++last release, see the git repository history: ++ ++http://sourceforge.net/p/openocd/code/ci/v0.12.0/log/?path= ++ ++ ++For older NEWS, see the NEWS files associated with each release ++(i.e. NEWS-). ++ ++For more information about contributing test reports, bug fixes, or new ++features and device support, please read the new Developer Manual (or ++the BUGS and PATCHES.txt files in the source archive). +diff --git a/configure.ac b/configure.ac +index eee42d424..7f0955f13 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + + AC_PREREQ([2.69]) +-AC_INIT([openocd], [0.12.0], ++AC_INIT([openocd], [0.12.0+dev], + [OpenOCD Mailing List ]) + AC_CONFIG_SRCDIR([src/openocd.c]) + AC_CONFIG_AUX_DIR([build-aux]) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0002-Deprecate-libjaylink-Git-submodule.patch b/meta-oe/recipes-devtools/openocd/openocd/0002-Deprecate-libjaylink-Git-submodule.patch new file mode 100644 index 000000000..539007fef --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0002-Deprecate-libjaylink-Git-submodule.patch @@ -0,0 +1,67 @@ +From 8bb926eb01022998ceefe666f8df102e59404015 Mon Sep 17 00:00:00 2001 +From: Marc Schink +Date: Sun, 22 May 2022 16:15:00 +0200 +Subject: [PATCH] Deprecate libjaylink Git submodule + +libjaylink was integrated into OpenOCD as a Git submodule, because at +that time there was no official release and no packages for it. +Today there are libjaylink packages for most popular distributions [1]. + +Removing libjaylink from OpenOCD reduces build complexity in both +projects and makes them more flexible with respect to the build system, +for example. + +Disable the libjaylink submodule by default and announce it as +deprecated feature that will be removed in the future. This gives +package maintainers time to package libjaylink if not already done. + +[1] https://repology.org/project/libjaylink/versions + +Change-Id: I6166ba4757aee5c89a0506de867072f58fa5ec4b +Signed-off-by: Marc Schink +Reviewed-on: https://review.openocd.org/c/openocd/+/7129 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + configure.ac | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 7f0955f13..4fcc91528 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -373,9 +373,9 @@ AC_ARG_ENABLE([jimtcl-maintainer], + [use_internal_jimtcl_maintainer=$enableval], [use_internal_jimtcl_maintainer=no]) + + AC_ARG_ENABLE([internal-libjaylink], +- AS_HELP_STRING([--disable-internal-libjaylink], +- [Disable building internal libjaylink]), +- [use_internal_libjaylink=$enableval], [use_internal_libjaylink=yes]) ++ AS_HELP_STRING([--enable-internal-libjaylink], ++ [Enable building internal libjaylink]), ++ [use_internal_libjaylink=$enableval], [use_internal_libjaylink=no]) + + AC_ARG_ENABLE([remote-bitbang], + AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbang jtag driver]), +@@ -713,7 +713,7 @@ AS_IF([test "x$enable_jlink" != "xno"], [ + AX_CONFIG_SUBDIR_OPTION([src/jtag/drivers/libjaylink], + [--enable-subproject-build]) + ], [ +- AC_MSG_ERROR([Internal libjaylink not found, run either 'git submodule init' and 'git submodule update' or disable internal libjaylink with --disable-internal-libjaylink.]) ++ AC_MSG_ERROR([Internal libjaylink not found, run 'git submodule init' and 'git submodule update'.]) + ]) + ]) + ]) +@@ -823,6 +823,12 @@ AC_CONFIG_FILES([ + ]) + AC_OUTPUT + ++AS_IF([test "x$enable_jlink" != "xno"], [ ++ AS_IF([test "x$use_internal_libjaylink" = "xyes"], [ ++ AC_MSG_WARN([Using the internal libjaylink is deprecated and will not be possible in the future.]) ++ ]]) ++) ++ + echo + echo + echo OpenOCD configuration summary diff --git a/meta-oe/recipes-devtools/openocd/openocd/0003-nds32-drop-it-together-with-aice-adapter-driver.patch b/meta-oe/recipes-devtools/openocd/openocd/0003-nds32-drop-it-together-with-aice-adapter-driver.patch new file mode 100644 index 000000000..01c9c1660 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0003-nds32-drop-it-together-with-aice-adapter-driver.patch @@ -0,0 +1,19095 @@ +From da34e36cdb542eac9370957b10853184f870e495 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Sep 2022 23:14:41 +0200 +Subject: [PATCH] nds32: drop it, together with aice adapter driver + +The target nds32 and its companion adapter aice have not received +any real improvement since 2013. +It has been hard to keep them aligned during the evolution of +OpenOCD code, with no way for maintainers to really check if they +are still working. +No real documentation is present for them in OpenOCD. +The nds32 code triggers ~50 errors/warnings with scan-build. + +The arch nds32 has been dropped from Linux kernel v5.18-rc1. + +For all the reasons above, this code has been deprecated with +commit 2e5df83de7f2 ("nds32: deprecate it, together with aice +adapter driver") and tagged to be dropped before v0.13.0. + +Let it r.i.p. in OpenOCD git history. + +While there, drop from checkpatch list the camelcase symbols that +where only used in this code. + +Change-Id: Ide52a217f2228e9da2f1cc5036c48f3536f26952 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7382 +Tested-by: jenkins +--- + README | 4 +- + configure.ac | 7 - + contrib/buildroot/openocd_be_defconfig | 1 - + doc/openocd.texi | 5 +- + src/jtag/Makefile.am | 5 - + src/jtag/aice/Makefile.am | 16 - + src/jtag/aice/aice_interface.c | 507 --- + src/jtag/aice/aice_interface.h | 14 - + src/jtag/aice/aice_pipe.c | 884 ----- + src/jtag/aice/aice_pipe.h | 20 - + src/jtag/aice/aice_port.c | 34 - + src/jtag/aice/aice_port.h | 224 -- + src/jtag/aice/aice_transport.c | 432 --- + src/jtag/aice/aice_transport.h | 13 - + src/jtag/aice/aice_usb.c | 4099 ------------------------ + src/jtag/aice/aice_usb.h | 122 - + src/jtag/interfaces.c | 6 - + src/jtag/startup.tcl | 6 - + src/rtos/FreeRTOS.c | 14 - + src/rtos/rtos_standard_stackings.c | 47 - + src/rtos/rtos_standard_stackings.h | 1 - + src/target/Makefile.am | 27 +- + src/target/nds32.c | 2613 --------------- + src/target/nds32.h | 447 --- + src/target/nds32_aice.c | 147 - + src/target/nds32_aice.h | 150 - + src/target/nds32_cmd.c | 1123 ------- + src/target/nds32_cmd.h | 15 - + src/target/nds32_disassembler.c | 3847 ---------------------- + src/target/nds32_disassembler.h | 45 - + src/target/nds32_edm.h | 106 - + src/target/nds32_insn.h | 67 - + src/target/nds32_reg.c | 369 --- + src/target/nds32_reg.h | 314 -- + src/target/nds32_tlb.c | 67 - + src/target/nds32_tlb.h | 36 - + src/target/nds32_v2.c | 774 ----- + src/target/nds32_v2.h | 31 - + src/target/nds32_v3.c | 510 --- + src/target/nds32_v3.h | 34 - + src/target/nds32_v3_common.c | 664 ---- + src/target/nds32_v3_common.h | 50 - + src/target/nds32_v3m.c | 495 --- + src/target/nds32_v3m.h | 40 - + src/target/target.c | 6 - + tcl/board/nds32_xc5.cfg | 7 - + tcl/interface/nds32-aice.cfg | 17 - + tcl/target/nds32v2.cfg | 12 - + tcl/target/nds32v3.cfg | 12 - + tcl/target/nds32v3m.cfg | 12 - + tools/scripts/camelcase.txt | 16 - + 51 files changed, 4 insertions(+), 18510 deletions(-) + delete mode 100644 src/jtag/aice/Makefile.am + delete mode 100644 src/jtag/aice/aice_interface.c + delete mode 100644 src/jtag/aice/aice_interface.h + delete mode 100644 src/jtag/aice/aice_pipe.c + delete mode 100644 src/jtag/aice/aice_pipe.h + delete mode 100644 src/jtag/aice/aice_port.c + delete mode 100644 src/jtag/aice/aice_port.h + delete mode 100644 src/jtag/aice/aice_transport.c + delete mode 100644 src/jtag/aice/aice_transport.h + delete mode 100644 src/jtag/aice/aice_usb.c + delete mode 100644 src/jtag/aice/aice_usb.h + delete mode 100644 src/target/nds32.c + delete mode 100644 src/target/nds32.h + delete mode 100644 src/target/nds32_aice.c + delete mode 100644 src/target/nds32_aice.h + delete mode 100644 src/target/nds32_cmd.c + delete mode 100644 src/target/nds32_cmd.h + delete mode 100644 src/target/nds32_disassembler.c + delete mode 100644 src/target/nds32_disassembler.h + delete mode 100644 src/target/nds32_edm.h + delete mode 100644 src/target/nds32_insn.h + delete mode 100644 src/target/nds32_reg.c + delete mode 100644 src/target/nds32_reg.h + delete mode 100644 src/target/nds32_tlb.c + delete mode 100644 src/target/nds32_tlb.h + delete mode 100644 src/target/nds32_v2.c + delete mode 100644 src/target/nds32_v2.h + delete mode 100644 src/target/nds32_v3.c + delete mode 100644 src/target/nds32_v3.h + delete mode 100644 src/target/nds32_v3_common.c + delete mode 100644 src/target/nds32_v3_common.h + delete mode 100644 src/target/nds32_v3m.c + delete mode 100644 src/target/nds32_v3m.h + delete mode 100644 tcl/board/nds32_xc5.cfg + delete mode 100644 tcl/interface/nds32-aice.cfg + delete mode 100644 tcl/target/nds32v2.cfg + delete mode 100644 tcl/target/nds32v3.cfg + delete mode 100644 tcl/target/nds32v3m.cfg + +diff --git a/README b/README +index 08b8117db..2f71cfc6a 100644 +--- a/README ++++ b/README +@@ -101,7 +101,7 @@ Supported hardware + JTAG adapters + ------------- + +-AICE, AM335x, ARM-JTAG-EW, ARM-USB-OCD, ARM-USB-TINY, AT91RM9200, axm0432, BCM2835, ++AM335x, ARM-JTAG-EW, ARM-USB-OCD, ARM-USB-TINY, AT91RM9200, axm0432, BCM2835, + Bus Blaster, Buspirate, Cadence DPI, Cadence vdebug, Chameleon, CMSIS-DAP, + Cortino, Cypress KitProg, DENX, Digilent JTAG-SMT2, DLC 5, DLP-USB1232H, + embedded projects, Espressif USB JTAG Programmer, +@@ -122,7 +122,7 @@ Debug targets + ARM: AArch64, ARM11, ARM7, ARM9, Cortex-A/R (v7-A/R), Cortex-M (ARMv{6/7/8}-M), + FA526, Feroceon/Dragonite, XScale. + ARCv2, AVR32, DSP563xx, DSP5680xx, EnSilica eSi-RISC, EJTAG (MIPS32, MIPS64), +-ESP32, ESP32-S2, ESP32-S3, Intel Quark, LS102x-SAP, NDS32, RISC-V, ST STM8, ++ESP32, ESP32-S2, ESP32-S3, Intel Quark, LS102x-SAP, RISC-V, ST STM8, + Xtensa. + + Flash drivers +diff --git a/configure.ac b/configure.ac +index 4fcc91528..cc7139c7c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -130,9 +130,6 @@ m4_define([USB1_ADAPTERS], + [[usbprog], [USBProg JTAG Programmer], [USBPROG]], + [[esp_usb_jtag], [Espressif JTAG Programmer], [ESP_USB_JTAG]]]) + +-m4_define([DEPRECATED_USB1_ADAPTERS], +- [[[aice], [Andes JTAG Programmer (deprecated)], [AICE]]]) +- + m4_define([HIDAPI_ADAPTERS], + [[[cmsis_dap], [CMSIS-DAP Compliant Debugger], [CMSIS_DAP_HID]], + [[nulink], [Nu-Link Programmer], [HLADAPTER_NULINK]]]) +@@ -264,8 +261,6 @@ AC_ARG_ADAPTERS([ + LIBJAYLINK_ADAPTERS + ],[auto]) + +-AC_ARG_ADAPTERS([DEPRECATED_USB1_ADAPTERS],[no]) +- + AC_ARG_ENABLE([parport], + AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]), + [build_parport=$enableval], [build_parport=no]) +@@ -684,7 +679,6 @@ m4_define([PROCESS_ADAPTERS], [ + ]) + + PROCESS_ADAPTERS([USB1_ADAPTERS], ["x$use_libusb1" = "xyes"], [libusb-1.x]) +-PROCESS_ADAPTERS([DEPRECATED_USB1_ADAPTERS], ["x$use_libusb1" = "xyes"], [libusb-1.x]) + PROCESS_ADAPTERS([HIDAPI_ADAPTERS], ["x$use_hidapi" = "xyes"], [hidapi]) + PROCESS_ADAPTERS([HIDAPI_USB1_ADAPTERS], ["x$use_hidapi" = "xyes" -a "x$use_libusb1" = "xyes"], [hidapi and libusb-1.x]) + PROCESS_ADAPTERS([LIBFTDI_ADAPTERS], ["x$use_libftdi" = "xyes"], [libftdi]) +@@ -834,7 +828,6 @@ echo + echo OpenOCD configuration summary + echo -------------------------------------------------- + m4_foreach([adapter], [USB1_ADAPTERS, +- DEPRECATED_USB1_ADAPTERS, + HIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, LIBFTDI_ADAPTERS, + LIBFTDI_USB1_ADAPTERS, + LIBGPIOD_ADAPTERS, +diff --git a/contrib/buildroot/openocd_be_defconfig b/contrib/buildroot/openocd_be_defconfig +index 2fe28f647..49a6ec2ac 100644 +--- a/contrib/buildroot/openocd_be_defconfig ++++ b/contrib/buildroot/openocd_be_defconfig +@@ -12,7 +12,6 @@ BR2_PACKAGE_OPENOCD_UBLASTER2=y + BR2_PACKAGE_OPENOCD_JLINK=y + BR2_PACKAGE_OPENOCD_OSDBM=y + BR2_PACKAGE_OPENOCD_OPENDOUS=y +-BR2_PACKAGE_OPENOCD_AICE=y + BR2_PACKAGE_OPENOCD_VSLLINK=y + BR2_PACKAGE_OPENOCD_USBPROG=y + BR2_PACKAGE_OPENOCD_RLINK=y +diff --git a/doc/openocd.texi b/doc/openocd.texi +index d8a5e86b4..c7fee3e71 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -2480,7 +2480,7 @@ This command is only available if your libusb1 is at least version 1.0.16. + Specifies the @var{serial_string} of the adapter to use. + If this command is not specified, serial strings are not checked. + Only the following adapter drivers use the serial string from this command: +-aice (aice_usb), arm-jtag-ew, cmsis_dap, ft232r, ftdi, hla (stlink, ti-icdi), jlink, kitprog, opendus, ++arm-jtag-ew, cmsis_dap, ft232r, ftdi, hla (stlink, ti-icdi), jlink, kitprog, opendus, + openjtag, osbdm, presto, rlink, st-link, usb_blaster (ublast2), usbprog, vsllink, xds110. + @end deffn + +@@ -4825,9 +4825,6 @@ specified, @xref{gdbportoverride,,option -gdb-port}.), and a fake ARM core will + be emulated to comply to GDB remote protocol. + @item @code{mips_m4k} -- a MIPS core. + @item @code{mips_mips64} -- a MIPS64 core. +-@item @code{nds32_v2} -- this is an Andes NDS32 v2 core (deprecated; would be removed in v0.13.0). +-@item @code{nds32_v3} -- this is an Andes NDS32 v3 core (deprecated; would be removed in v0.13.0). +-@item @code{nds32_v3m} -- this is an Andes NDS32 v3m core (deprecated; would be removed in v0.13.0). + @item @code{or1k} -- this is an OpenRISC 1000 core. + The current implementation supports three JTAG TAP cores: + @itemize @minus +diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am +index 43c6f8b27..7ce4adc29 100644 +--- a/src/jtag/Makefile.am ++++ b/src/jtag/Makefile.am +@@ -9,11 +9,6 @@ include %D%/hla/Makefile.am + %C%_libjtag_la_LIBADD += $(top_builddir)/%D%/hla/libocdhla.la + endif + +-if AICE +-include %D%/aice/Makefile.am +-%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/aice/libocdaice.la +-endif +- + include %D%/drivers/Makefile.am + %C%_libjtag_la_LIBADD += $(top_builddir)/%D%/drivers/libocdjtagdrivers.la + +diff --git a/src/jtag/aice/Makefile.am b/src/jtag/aice/Makefile.am +deleted file mode 100644 +index bc5dac1e2..000000000 +--- a/src/jtag/aice/Makefile.am ++++ /dev/null +@@ -1,16 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-noinst_LTLIBRARIES += %D%/libocdaice.la +- +-%C%_libocdaice_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) +-%C%_libocdaice_la_SOURCES = \ +- %D%/aice_transport.c \ +- %D%/aice_interface.c \ +- %D%/aice_port.c \ +- %D%/aice_usb.c \ +- %D%/aice_pipe.c \ +- %D%/aice_transport.h \ +- %D%/aice_interface.h \ +- %D%/aice_port.h \ +- %D%/aice_usb.h \ +- %D%/aice_pipe.h +diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c +deleted file mode 100644 +index 89f82a0ae..000000000 +--- a/src/jtag/aice/aice_interface.c ++++ /dev/null +@@ -1,507 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include "aice_usb.h" +- +-#define AICE_KHZ_TO_SPEED_MAP_SIZE 16 +-static const int aice_khz_to_speed_map[AICE_KHZ_TO_SPEED_MAP_SIZE] = { +- 30000, +- 15000, +- 7500, +- 3750, +- 1875, +- 937, +- 468, +- 234, +- 48000, +- 24000, +- 12000, +- 6000, +- 3000, +- 1500, +- 750, +- 375, +-}; +- +-static const struct aice_port *aice_port; +-static struct aice_port_param_s param; +-static uint32_t retry_times; +-static uint32_t count_to_check_dbger; +- +-/***************************************************************************/ +-/* External interface implementation */ +-static uint32_t aice_target_id_codes[AICE_MAX_NUM_CORE]; +-static uint8_t aice_num_of_target_id_codes; +- +-/***************************************************************************/ +-/* AICE operations */ +-int aice_init_targets(void) +-{ +- int res; +- struct target *target; +- struct aice_port_s *aice; +- +- LOG_DEBUG("aice_init_targets"); +- +- if (aice_num_of_target_id_codes == 0) { +- res = aice_port->api->idcode(aice_target_id_codes, &aice_num_of_target_id_codes); +- if (res != ERROR_OK) { +- LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore " +- "JTAG Manufacture ID in the JTAG scan chain. " +- "Failed to access EDM registers. -->"); +- return res; +- } +- } +- +- for (target = all_targets; target; target = target->next) { +- target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position]; +- +- unsigned ii, limit = target->tap->expected_ids_cnt; +- int found = 0; +- +- for (ii = 0; ii < limit; ii++) { +- uint32_t expected = target->tap->expected_ids[ii]; +- +- /* treat "-expected-id 0" as a "don't-warn" wildcard */ +- if (!expected || (target->tap->idcode == expected)) { +- found = 1; +- break; +- } +- } +- +- if (found == 0) { +- LOG_ERROR +- ("aice_init_targets: target not found: idcode: %" PRIx32, +- target->tap->idcode); +- return ERROR_FAIL; +- } +- +- aice = calloc(1, sizeof(struct aice_port_s)); +- aice->port = aice_port; +- aice->coreid = target->tap->abs_chain_position; +- +- target->tap->priv = aice; +- target->tap->hasidcode = 1; +- } +- +- return ERROR_OK; +-} +- +-/***************************************************************************/ +-/* End of External interface implementation */ +- +-/* initial aice +- * 1. open usb +- * 2. get/show version number +- * 3. reset +- */ +-static int aice_init(void) +-{ +- if (aice_port->api->open(¶m) != ERROR_OK) { +- LOG_ERROR("Cannot find AICE Interface! Please check " +- "connection and permissions."); +- return ERROR_JTAG_INIT_FAILED; +- } +- +- aice_port->api->set_retry_times(retry_times); +- aice_port->api->set_count_to_check_dbger(count_to_check_dbger); +- +- LOG_INFO("AICE JTAG Interface ready"); +- +- return ERROR_OK; +-} +- +-/* cleanup aice resource +- * close usb +- */ +-static int aice_quit(void) +-{ +- aice_port->api->close(); +- return ERROR_OK; +-} +- +-static int aice_execute_reset(struct jtag_command *cmd) +-{ +- static int last_trst; +- int retval = ERROR_OK; +- +- LOG_DEBUG_IO("reset trst: %d", cmd->cmd.reset->trst); +- +- if (cmd->cmd.reset->trst != last_trst) { +- if (cmd->cmd.reset->trst) +- retval = aice_port->api->reset(); +- +- last_trst = cmd->cmd.reset->trst; +- } +- +- return retval; +-} +- +-static int aice_execute_command(struct jtag_command *cmd) +-{ +- int retval; +- +- switch (cmd->type) { +- case JTAG_RESET: +- retval = aice_execute_reset(cmd); +- break; +- default: +- retval = ERROR_OK; +- break; +- } +- return retval; +-} +- +-/* aice has no need to implement jtag execution model +-*/ +-static int aice_execute_queue(void) +-{ +- struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ +- int retval; +- +- retval = ERROR_OK; +- +- while (cmd) { +- if (aice_execute_command(cmd) != ERROR_OK) +- retval = ERROR_JTAG_QUEUE_FAILED; +- +- cmd = cmd->next; +- } +- +- return retval; +-} +- +-/* set jtag frequency(base frequency/frequency divider) to your jtag adapter */ +-static int aice_speed(int speed) +-{ +- return aice_port->api->set_jtag_clock(speed); +-} +- +-/* convert jtag adapter frequency(base frequency/frequency divider) to +- * human readable KHz value */ +-static int aice_speed_div(int speed, int *khz) +-{ +- *khz = aice_khz_to_speed_map[speed]; +- +- return ERROR_OK; +-} +- +-/* convert human readable KHz value to jtag adapter frequency +- * (base frequency/frequency divider) */ +-static int aice_khz(int khz, int *jtag_speed) +-{ +- int i; +- for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) { +- if (khz == aice_khz_to_speed_map[i]) { +- if (i >= 8) +- *jtag_speed = i | AICE_TCK_CONTROL_TCK3048; +- else +- *jtag_speed = i; +- break; +- } +- } +- +- if (i == AICE_KHZ_TO_SPEED_MAP_SIZE) { +- LOG_INFO("No support the jtag clock: %d", khz); +- LOG_INFO("Supported jtag clocks are:"); +- +- for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) +- LOG_INFO("* %d", aice_khz_to_speed_map[i]); +- +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-int aice_scan_jtag_chain(void) +-{ +- LOG_DEBUG("=== %s ===", __func__); +- uint8_t num_of_idcode = 0; +- struct target *target; +- +- int res = aice_port->api->idcode(aice_target_id_codes, &num_of_idcode); +- if (res != ERROR_OK) { +- LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore " +- "JTAG Manufacture ID in the JTAG scan chain. " +- "Failed to access EDM registers. -->"); +- return res; +- } +- +- for (unsigned int i = 0; i < num_of_idcode; i++) +- LOG_DEBUG("id_codes[%u] = 0x%" PRIx32, i, aice_target_id_codes[i]); +- +- /* Update tap idcode */ +- for (target = all_targets; target; target = target->next) +- target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position]; +- +- return ERROR_OK; +-} +- +-/***************************************************************************/ +-/* Command handlers */ +-COMMAND_HANDLER(aice_handle_aice_info_command) +-{ +- LOG_DEBUG("aice_handle_aice_info_command"); +- +- command_print(CMD, "Description: %s", param.device_desc); +- command_print(CMD, "Serial number: %s", adapter_get_required_serial()); +- if (strncmp(aice_port->name, "aice_pipe", 9) == 0) +- command_print(CMD, "Adapter: %s", param.adapter_name); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(aice_handle_aice_port_command) +-{ +- LOG_DEBUG("aice_handle_aice_port_command"); +- +- if (CMD_ARGC != 1) { +- LOG_ERROR("Need exactly one argument to 'aice port'"); +- return ERROR_COMMAND_SYNTAX_ERROR; +- } +- +- for (const struct aice_port *l = aice_port_get_list(); l->name; l++) { +- if (strcmp(l->name, CMD_ARGV[0]) == 0) { +- aice_port = l; +- return ERROR_OK; +- } +- } +- +- LOG_ERROR("No AICE port '%s' found", CMD_ARGV[0]); +- return ERROR_FAIL; +-} +- +-COMMAND_HANDLER(aice_handle_aice_desc_command) +-{ +- LOG_DEBUG("aice_handle_aice_desc_command"); +- +- if (CMD_ARGC == 1) +- param.device_desc = strdup(CMD_ARGV[0]); +- else +- LOG_ERROR("expected exactly one argument to aice desc "); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(aice_handle_aice_vid_pid_command) +-{ +- LOG_DEBUG("aice_handle_aice_vid_pid_command"); +- +- if (CMD_ARGC != 2) { +- LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)"); +- return ERROR_COMMAND_SYNTAX_ERROR; +- } +- +- COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], param.vid); +- COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], param.pid); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(aice_handle_aice_adapter_command) +-{ +- LOG_DEBUG("aice_handle_aice_adapter_command"); +- +- if (CMD_ARGC == 1) +- param.adapter_name = strdup(CMD_ARGV[0]); +- else +- LOG_ERROR("expected exactly one argument to aice adapter "); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(aice_handle_aice_retry_times_command) +-{ +- LOG_DEBUG("aice_handle_aice_retry_times_command"); +- +- if (CMD_ARGC == 1) +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], retry_times); +- else +- LOG_ERROR("expected exactly one argument to aice retry_times "); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command) +-{ +- LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command"); +- +- if (CMD_ARGC == 1) +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], count_to_check_dbger); +- else +- LOG_ERROR("expected exactly one argument to aice count_to_check_dbger " +- ""); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command) +-{ +- LOG_DEBUG("aice_handle_aice_custom_srst_script_command"); +- +- if (CMD_ARGC > 0) { +- aice_port->api->set_custom_srst_script(CMD_ARGV[0]); +- return ERROR_OK; +- } +- +- return ERROR_FAIL; +-} +- +-COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command) +-{ +- LOG_DEBUG("aice_handle_aice_custom_trst_script_command"); +- +- if (CMD_ARGC > 0) { +- aice_port->api->set_custom_trst_script(CMD_ARGV[0]); +- return ERROR_OK; +- } +- +- return ERROR_FAIL; +-} +- +-COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command) +-{ +- LOG_DEBUG("aice_handle_aice_custom_restart_script_command"); +- +- if (CMD_ARGC > 0) { +- aice_port->api->set_custom_restart_script(CMD_ARGV[0]); +- return ERROR_OK; +- } +- +- return ERROR_FAIL; +-} +- +-COMMAND_HANDLER(aice_handle_aice_reset_command) +-{ +- LOG_DEBUG("aice_handle_aice_reset_command"); +- +- return aice_port->api->reset(); +-} +- +- +-static const struct command_registration aice_subcommand_handlers[] = { +- { +- .name = "info", +- .handler = &aice_handle_aice_info_command, +- .mode = COMMAND_EXEC, +- .help = "show aice info", +- .usage = "", +- }, +- { +- .name = "port", +- .handler = &aice_handle_aice_port_command, +- .mode = COMMAND_CONFIG, +- .help = "set the port of the AICE", +- .usage = "['aice_pipe'|'aice_usb']", +- }, +- { +- .name = "desc", +- .handler = &aice_handle_aice_desc_command, +- .mode = COMMAND_CONFIG, +- .help = "set the aice device description", +- .usage = "[description string]", +- }, +- { +- .name = "vid_pid", +- .handler = &aice_handle_aice_vid_pid_command, +- .mode = COMMAND_CONFIG, +- .help = "the vendor and product ID of the AICE device", +- .usage = "(vid pid)*", +- }, +- { +- .name = "adapter", +- .handler = &aice_handle_aice_adapter_command, +- .mode = COMMAND_CONFIG, +- .help = "set the file name of adapter", +- .usage = "[adapter name]", +- }, +- { +- .name = "retry_times", +- .handler = &aice_handle_aice_retry_times_command, +- .mode = COMMAND_CONFIG, +- .help = "set retry times as AICE timeout", +- .usage = "num_of_retry", +- }, +- { +- .name = "count_to_check_dbger", +- .handler = &aice_handle_aice_count_to_check_dbger_command, +- .mode = COMMAND_CONFIG, +- .help = "set retry times as checking $DBGER status", +- .usage = "count_of_checking", +- }, +- { +- .name = "custom_srst_script", +- .handler = &aice_handle_aice_custom_srst_script_command, +- .mode = COMMAND_CONFIG, +- .usage = "script_file_name", +- .help = "set custom srst script", +- }, +- { +- .name = "custom_trst_script", +- .handler = &aice_handle_aice_custom_trst_script_command, +- .mode = COMMAND_CONFIG, +- .usage = "script_file_name", +- .help = "set custom trst script", +- }, +- { +- .name = "custom_restart_script", +- .handler = &aice_handle_aice_custom_restart_script_command, +- .mode = COMMAND_CONFIG, +- .usage = "script_file_name", +- .help = "set custom restart script", +- }, +- { +- .name = "reset", +- .handler = &aice_handle_aice_reset_command, +- .mode = COMMAND_EXEC, +- .usage = "", +- .help = "reset AICE", +- }, +- COMMAND_REGISTRATION_DONE +-}; +- +-static const struct command_registration aice_command_handlers[] = { +- { +- .name = "aice", +- .mode = COMMAND_ANY, +- .help = "perform aice management", +- .usage = "[subcommand]", +- .chain = aice_subcommand_handlers, +- }, +- COMMAND_REGISTRATION_DONE +-}; +-/***************************************************************************/ +-/* End of Command handlers */ +- +-static struct jtag_interface aice_interface = { +- .execute_queue = aice_execute_queue, +-}; +- +-struct adapter_driver aice_adapter_driver = { +- .name = "aice", +- .transports = aice_transports, +- .commands = aice_command_handlers, +- +- .init = aice_init, +- .quit = aice_quit, +- .speed = aice_speed, /* set interface speed */ +- .khz = aice_khz, /* convert khz to interface speed value */ +- .speed_div = aice_speed_div, /* return readable value */ +- +- .jtag_ops = &aice_interface, +-}; +diff --git a/src/jtag/aice/aice_interface.h b/src/jtag/aice/aice_interface.h +deleted file mode 100644 +index 615e90f2e..000000000 +--- a/src/jtag/aice/aice_interface.h ++++ /dev/null +@@ -1,14 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_JTAG_AICE_AICE_INTERFACE_H +-#define OPENOCD_JTAG_AICE_AICE_INTERFACE_H +- +-int aice_init_targets(void); +-int aice_scan_jtag_chain(void); +- +-#endif /* OPENOCD_JTAG_AICE_AICE_INTERFACE_H */ +diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c +deleted file mode 100644 +index 1ee2d88b4..000000000 +--- a/src/jtag/aice/aice_pipe.c ++++ /dev/null +@@ -1,884 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +- +-#ifdef _WIN32 +-#include +-#else +-#include +-#endif +- +-#include +-#include +-#include "aice_port.h" +-#include "aice_pipe.h" +- +-#define AICE_PIPE_MAXLINE 8192 +- +-#ifdef _WIN32 +-PROCESS_INFORMATION proc_info; +- +-static HANDLE aice_pipe_output[2]; +-static HANDLE aice_pipe_input[2]; +- +-static int aice_pipe_write(const void *buffer, int count) +-{ +- BOOL success; +- DWORD written; +- +- success = WriteFile(aice_pipe_output[1], buffer, count, &written, NULL); +- if (!success) { +- LOG_ERROR("(WIN32) write to pipe failed, error code: 0x%08l" PRIx32, GetLastError()); +- return -1; +- } +- +- return written; +-} +- +-static int aice_pipe_read(void *buffer, int count) +-{ +- BOOL success; +- DWORD has_read; +- +- success = ReadFile(aice_pipe_input[0], buffer, count, &has_read, NULL); +- if (!success || (has_read == 0)) { +- LOG_ERROR("(WIN32) read from pipe failed, error code: 0x%08l" PRIx32, GetLastError()); +- return -1; +- } +- +- return has_read; +-} +- +-static int aice_pipe_child_init(struct aice_port_param_s *param) +-{ +- STARTUPINFO start_info; +- BOOL success; +- +- ZeroMemory(&proc_info, sizeof(PROCESS_INFORMATION)); +- ZeroMemory(&start_info, sizeof(STARTUPINFO)); +- start_info.cb = sizeof(STARTUPINFO); +- start_info.hStdError = aice_pipe_input[1]; +- start_info.hStdOutput = aice_pipe_input[1]; +- start_info.hStdInput = aice_pipe_output[0]; +- start_info.dwFlags |= STARTF_USESTDHANDLES; +- +- success = CreateProcess(NULL, +- param->adapter_name, +- NULL, +- NULL, +- TRUE, +- 0, +- NULL, +- NULL, +- &start_info, +- &proc_info); +- +- if (!success) { +- LOG_ERROR("Create new process failed"); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_pipe_parent_init(struct aice_port_param_s *param) +-{ +- /* send open to adapter */ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_OPEN; +- set_u16(command + 1, param->vid); +- set_u16(command + 3, param->pid); +- +- if (aice_pipe_write(command, 5) != 5) { +- LOG_ERROR("write failed\n"); +- return ERROR_FAIL; +- } +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) { +- LOG_ERROR("read failed\n"); +- return ERROR_FAIL; +- } +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_open(struct aice_port_param_s *param) +-{ +- SECURITY_ATTRIBUTES attribute; +- +- attribute.nLength = sizeof(SECURITY_ATTRIBUTES); +- attribute.bInheritHandle = TRUE; +- attribute.lpSecurityDescriptor = NULL; +- +- if (!CreatePipe(&aice_pipe_output[0], &aice_pipe_output[1], +- &attribute, AICE_PIPE_MAXLINE)) { +- LOG_ERROR("Create pipes failed"); +- return ERROR_FAIL; +- } +- if (!CreatePipe(&aice_pipe_input[0], &aice_pipe_input[1], +- &attribute, AICE_PIPE_MAXLINE)) { +- LOG_ERROR("Create pipes failed"); +- return ERROR_FAIL; +- } +- +- /* do not inherit aice_pipe_output[1] & aice_pipe_input[0] to child process */ +- if (!SetHandleInformation(aice_pipe_output[1], HANDLE_FLAG_INHERIT, 0)) +- return ERROR_FAIL; +- if (!SetHandleInformation(aice_pipe_input[0], HANDLE_FLAG_INHERIT, 0)) +- return ERROR_FAIL; +- +- aice_pipe_child_init(param); +- +- aice_pipe_parent_init(param); +- +- return ERROR_OK; +-} +- +-#else +- +-static int aice_pipe_output[2]; +-static int aice_pipe_input[2]; +- +-static int aice_pipe_write(const void *buffer, int count) +-{ +- if (write(aice_pipe_output[1], buffer, count) != count) { +- LOG_ERROR("write to pipe failed"); +- return -1; +- } +- +- return count; +-} +- +-static int aice_pipe_read(void *buffer, int count) +-{ +- int n; +- int64_t then, cur; +- +- then = timeval_ms(); +- +- while (1) { +- n = read(aice_pipe_input[0], buffer, count); +- +- if ((n == -1) && (errno == EAGAIN)) { +- cur = timeval_ms(); +- if (cur - then > 500) +- keep_alive(); +- continue; +- } else if (n > 0) +- break; +- else { +- LOG_ERROR("read from pipe failed"); +- break; +- } +- } +- +- return n; +-} +- +-static int aice_pipe_child_init(struct aice_port_param_s *param) +-{ +- close(aice_pipe_output[1]); +- close(aice_pipe_input[0]); +- +- if (aice_pipe_output[0] != STDIN_FILENO) { +- if (dup2(aice_pipe_output[0], STDIN_FILENO) != STDIN_FILENO) { +- LOG_ERROR("Map aice_pipe to STDIN failed"); +- return ERROR_FAIL; +- } +- close(aice_pipe_output[0]); +- } +- +- if (aice_pipe_input[1] != STDOUT_FILENO) { +- if (dup2(aice_pipe_input[1], STDOUT_FILENO) != STDOUT_FILENO) { +- LOG_ERROR("Map aice_pipe to STDOUT failed"); +- return ERROR_FAIL; +- } +- close(aice_pipe_input[1]); +- } +- +- if (execl(param->adapter_name, param->adapter_name, (char *)0) < 0) { +- LOG_ERROR("Execute aice_pipe failed"); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_pipe_parent_init(struct aice_port_param_s *param) +-{ +- close(aice_pipe_output[0]); +- close(aice_pipe_input[1]); +- +- /* set read end of pipe as non-blocking */ +- if (fcntl(aice_pipe_input[0], F_SETFL, O_NONBLOCK)) +- return ERROR_FAIL; +- +- /* send open to adapter */ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_OPEN; +- set_u16(command + 1, param->vid); +- set_u16(command + 3, param->pid); +- +- if (aice_pipe_write(command, 5) != 5) { +- LOG_ERROR("write failed\n"); +- return ERROR_FAIL; +- } +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) { +- LOG_ERROR("read failed\n"); +- return ERROR_FAIL; +- } +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static void sig_pipe(int signo) +-{ +- exit(1); +-} +- +-static int aice_pipe_open(struct aice_port_param_s *param) +-{ +- pid_t pid; +- +- if (signal(SIGPIPE, sig_pipe) == SIG_ERR) { +- LOG_ERROR("Register SIGPIPE handler failed"); +- return ERROR_FAIL; +- } +- +- if (pipe(aice_pipe_output) < 0 || pipe(aice_pipe_input) < 0) { +- LOG_ERROR("Create pipes failed"); +- return ERROR_FAIL; +- } +- +- pid = fork(); +- if (pid < 0) { +- LOG_ERROR("Fork new process failed"); +- return ERROR_FAIL; +- } else if (pid == 0) { +- if (aice_pipe_child_init(param) != ERROR_OK) { +- LOG_ERROR("AICE_PIPE child process initial error"); +- return ERROR_FAIL; +- } else { +- if (aice_pipe_parent_init(param) != ERROR_OK) { +- LOG_ERROR("AICE_PIPE parent process initial error"); +- return ERROR_FAIL; +- } +- } +- } +- +- return ERROR_OK; +-} +-#endif +- +-static int aice_pipe_close(void) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_CLOSE; +- +- if (aice_pipe_write(command, 1) != 1) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) { +-#ifdef _WIN32 +- WaitForSingleObject(proc_info.hProcess, INFINITE); +- CloseHandle(proc_info.hProcess); +- CloseHandle(proc_info.hThread); +-#endif +- return ERROR_OK; +- } else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_idcode(uint32_t *idcode, uint8_t *num_of_idcode) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_IDCODE; +- +- if (aice_pipe_write(command, 1) != 1) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- *num_of_idcode = line[0]; +- +- if ((*num_of_idcode == 0) || (*num_of_idcode >= 16)) +- return ERROR_FAIL; +- +- for (int i = 0 ; i < *num_of_idcode ; i++) +- idcode[i] = get_u32(line + i * 4 + 1); +- +- return ERROR_OK; +-} +- +-static int aice_pipe_state(uint32_t coreid, enum aice_target_state_s *state) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_STATE; +- +- if (aice_pipe_write(command, 1) != 1) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- *state = (enum aice_target_state_s)line[0]; +- +- return ERROR_OK; +-} +- +-static int aice_pipe_reset(void) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_RESET; +- +- if (aice_pipe_write(command, 1) != 1) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_assert_srst(uint32_t coreid, enum aice_srst_type_s srst) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_ASSERT_SRST; +- command[1] = srst; +- +- if (aice_pipe_write(command, 2) != 2) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_run(uint32_t coreid) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_RUN; +- +- if (aice_pipe_write(command, 1) != 1) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_halt(uint32_t coreid) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_HALT; +- +- if (aice_pipe_write(command, 1) != 1) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_READ_REG; +- set_u32(command + 1, num); +- +- if (aice_pipe_write(command, 5) != 5) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- *val = get_u32(line); +- +- return ERROR_OK; +-} +- +-static int aice_pipe_write_reg(uint32_t coreid, uint32_t num, uint32_t val) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_WRITE_REG; +- set_u32(command + 1, num); +- set_u32(command + 5, val); +- +- if (aice_pipe_write(command, 9) != 9) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_read_reg_64(uint32_t coreid, uint32_t num, uint64_t *val) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_READ_REG_64; +- set_u32(command + 1, num); +- +- if (aice_pipe_write(command, 5) != 5) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- *val = (((uint64_t)get_u32(line + 4)) << 32) | get_u32(line); +- +- return ERROR_OK; +-} +- +-static int aice_pipe_write_reg_64(uint32_t coreid, uint32_t num, uint64_t val) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_WRITE_REG_64; +- set_u32(command + 1, num); +- set_u32(command + 5, val & 0xFFFFFFFF); +- set_u32(command + 9, (val >> 32) & 0xFFFFFFFF); +- +- if (aice_pipe_write(command, 13) != 9) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_step(uint32_t coreid) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_STEP; +- +- if (aice_pipe_write(command, 1) != 1) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_read_mem_unit(uint32_t coreid, uint32_t addr, uint32_t size, +- uint32_t count, uint8_t *buffer) +-{ +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_READ_MEM_UNIT; +- set_u32(command + 1, addr); +- set_u32(command + 5, size); +- set_u32(command + 9, count); +- +- if (aice_pipe_write(command, 13) != 13) +- return ERROR_FAIL; +- +- if (aice_pipe_read(buffer, size * count) < 0) +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int aice_pipe_write_mem_unit(uint32_t coreid, uint32_t addr, uint32_t size, +- uint32_t count, const uint8_t *buffer) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_WRITE_MEM_UNIT; +- set_u32(command + 1, addr); +- set_u32(command + 5, size); +- set_u32(command + 9, count); +- +- /* WRITE_MEM_UNIT|addr|size|count|data */ +- memcpy(command + 13, buffer, size * count); +- +- if (aice_pipe_write(command, 13 + size * count) < 0) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int aice_pipe_read_mem_bulk(uint32_t coreid, uint32_t addr, +- uint32_t length, uint8_t *buffer) +-{ +- char line[AICE_PIPE_MAXLINE + 1]; +- char command[AICE_PIPE_MAXLINE]; +- uint32_t remain_len = length; +- uint32_t prepare_len; +- char *received_line; +- uint32_t received_len; +- int read_len; +- +- command[0] = AICE_READ_MEM_BULK; +- set_u32(command + 1, addr); +- set_u32(command + 5, length); +- +- if (aice_pipe_write(command, 9) < 0) +- return ERROR_FAIL; +- +- while (remain_len > 0) { +- if (remain_len > AICE_PIPE_MAXLINE) +- prepare_len = AICE_PIPE_MAXLINE; +- else +- prepare_len = remain_len; +- +- prepare_len++; +- received_len = 0; +- received_line = line; +- do { +- read_len = aice_pipe_read(received_line, prepare_len - received_len); +- if (read_len < 0) +- return ERROR_FAIL; +- received_line += read_len; +- received_len += read_len; +- } while (received_len < prepare_len); +- +- if (line[0] != AICE_OK) +- return ERROR_FAIL; +- +- prepare_len--; +- memcpy(buffer, line + 1, prepare_len); +- remain_len -= prepare_len; +- buffer += prepare_len; +- } +- +- return ERROR_OK; +-} +- +-static int aice_pipe_write_mem_bulk(uint32_t coreid, uint32_t addr, +- uint32_t length, const uint8_t *buffer) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE + 4]; +- uint32_t remain_len = length; +- uint32_t written_len = 0; +- uint32_t write_len; +- +- command[0] = AICE_WRITE_MEM_BULK; +- set_u32(command + 1, addr); +- set_u32(command + 5, length); +- +- /* Send command first */ +- if (aice_pipe_write(command, 9) < 0) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_ERROR) +- return ERROR_FAIL; +- +- while (remain_len > 0) { +- if (remain_len > AICE_PIPE_MAXLINE) +- write_len = AICE_PIPE_MAXLINE; +- else +- write_len = remain_len; +- +- set_u32(command, write_len); +- memcpy(command + 4, buffer + written_len, write_len); /* data only */ +- +- if (aice_pipe_write(command, write_len + 4) < 0) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_ERROR) +- return ERROR_FAIL; +- +- remain_len -= write_len; +- written_len += write_len; +- } +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_read_debug_reg(uint32_t coreid, uint32_t addr, uint32_t *val) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_READ_DEBUG_REG; +- set_u32(command + 1, addr); +- +- if (aice_pipe_write(command, 5) != 5) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- *val = get_u32(line); +- +- return ERROR_OK; +-} +- +-static int aice_pipe_write_debug_reg(uint32_t coreid, uint32_t addr, const uint32_t val) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_WRITE_DEBUG_REG; +- set_u32(command + 1, addr); +- set_u32(command + 5, val); +- +- if (aice_pipe_write(command, 9) != 9) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_set_jtag_clock(uint32_t a_clock) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_SET_JTAG_CLOCK; +- set_u32(command + 1, a_clock); +- +- if (aice_pipe_write(command, 5) != 5) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_memory_access(uint32_t coreid, enum nds_memory_access access_channel) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_MEMORY_ACCESS; +- set_u32(command + 1, access_channel); +- +- if (aice_pipe_write(command, 5) != 5) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_memory_mode(uint32_t coreid, enum nds_memory_select mem_select) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_MEMORY_MODE; +- set_u32(command + 1, mem_select); +- +- if (aice_pipe_write(command, 5) != 5) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_read_tlb(uint32_t coreid, target_addr_t virtual_address, +- target_addr_t *physical_address) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_READ_TLB; +- set_u32(command + 1, virtual_address); +- +- if (aice_pipe_write(command, 5) != 5) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) { +- *physical_address = get_u32(line + 1); +- return ERROR_OK; +- } else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_cache_ctl(uint32_t coreid, uint32_t subtype, uint32_t address) +-{ +- char line[AICE_PIPE_MAXLINE]; +- char command[AICE_PIPE_MAXLINE]; +- +- command[0] = AICE_CACHE_CTL; +- set_u32(command + 1, subtype); +- set_u32(command + 5, address); +- +- if (aice_pipe_write(command, 9) != 9) +- return ERROR_FAIL; +- +- if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) +- return ERROR_FAIL; +- +- if (line[0] == AICE_OK) +- return ERROR_OK; +- else +- return ERROR_FAIL; +-} +- +-static int aice_pipe_set_retry_times(uint32_t a_retry_times) +-{ +- return ERROR_OK; +-} +- +-/** */ +-struct aice_port_api_s aice_pipe = { +- /** */ +- .open = aice_pipe_open, +- /** */ +- .close = aice_pipe_close, +- /** */ +- .idcode = aice_pipe_idcode, +- /** */ +- .set_jtag_clock = aice_pipe_set_jtag_clock, +- /** */ +- .state = aice_pipe_state, +- /** */ +- .reset = aice_pipe_reset, +- /** */ +- .assert_srst = aice_pipe_assert_srst, +- /** */ +- .run = aice_pipe_run, +- /** */ +- .halt = aice_pipe_halt, +- /** */ +- .step = aice_pipe_step, +- /** */ +- .read_reg = aice_pipe_read_reg, +- /** */ +- .write_reg = aice_pipe_write_reg, +- /** */ +- .read_reg_64 = aice_pipe_read_reg_64, +- /** */ +- .write_reg_64 = aice_pipe_write_reg_64, +- /** */ +- .read_mem_unit = aice_pipe_read_mem_unit, +- /** */ +- .write_mem_unit = aice_pipe_write_mem_unit, +- /** */ +- .read_mem_bulk = aice_pipe_read_mem_bulk, +- /** */ +- .write_mem_bulk = aice_pipe_write_mem_bulk, +- /** */ +- .read_debug_reg = aice_pipe_read_debug_reg, +- /** */ +- .write_debug_reg = aice_pipe_write_debug_reg, +- +- /** */ +- .memory_access = aice_pipe_memory_access, +- /** */ +- .memory_mode = aice_pipe_memory_mode, +- +- /** */ +- .read_tlb = aice_pipe_read_tlb, +- +- /** */ +- .cache_ctl = aice_pipe_cache_ctl, +- +- /** */ +- .set_retry_times = aice_pipe_set_retry_times, +-}; +diff --git a/src/jtag/aice/aice_pipe.h b/src/jtag/aice/aice_pipe.h +deleted file mode 100644 +index 5a1f4107f..000000000 +--- a/src/jtag/aice/aice_pipe.h ++++ /dev/null +@@ -1,20 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_JTAG_AICE_AICE_PIPE_H +-#define OPENOCD_JTAG_AICE_AICE_PIPE_H +- +-#include +- +-#define set_u32(buffer, value) h_u32_to_le((uint8_t *)buffer, value) +-#define set_u16(buffer, value) h_u16_to_le((uint8_t *)buffer, value) +-#define get_u32(buffer) le_to_h_u32((const uint8_t *)buffer) +-#define get_u16(buffer) le_to_h_u16((const uint8_t *)buffer) +- +-extern struct aice_port_api_s aice_pipe; +- +-#endif /* OPENOCD_JTAG_AICE_AICE_PIPE_H */ +diff --git a/src/jtag/aice/aice_port.c b/src/jtag/aice/aice_port.c +deleted file mode 100644 +index ac38cec3a..000000000 +--- a/src/jtag/aice/aice_port.c ++++ /dev/null +@@ -1,34 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include "aice_usb.h" +-#include "aice_pipe.h" +-#include "aice_port.h" +- +-static const struct aice_port aice_ports[] = { +- { +- .name = "aice_usb", +- .type = AICE_PORT_AICE_USB, +- .api = &aice_usb_api, +- }, +- { +- .name = "aice_pipe", +- .type = AICE_PORT_AICE_PIPE, +- .api = &aice_pipe, +- }, +- {.name = NULL, /* END OF TABLE */ }, +-}; +- +-/** */ +-const struct aice_port *aice_port_get_list(void) +-{ +- return aice_ports; +-} +diff --git a/src/jtag/aice/aice_port.h b/src/jtag/aice/aice_port.h +deleted file mode 100644 +index fb914d853..000000000 +--- a/src/jtag/aice/aice_port.h ++++ /dev/null +@@ -1,224 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_JTAG_AICE_AICE_PORT_H +-#define OPENOCD_JTAG_AICE_AICE_PORT_H +- +-#include +- +-#define AICE_MAX_NUM_CORE (0x10) +- +-#define ERROR_AICE_DISCONNECT (-200) +-#define ERROR_AICE_TIMEOUT (-201) +- +-enum aice_target_state_s { +- AICE_DISCONNECT = 0, +- AICE_TARGET_DETACH, +- AICE_TARGET_UNKNOWN, +- AICE_TARGET_RUNNING, +- AICE_TARGET_HALTED, +- AICE_TARGET_RESET, +- AICE_TARGET_DEBUG_RUNNING, +-}; +- +-enum aice_srst_type_s { +- AICE_SRST = 0x1, +- AICE_RESET_HOLD = 0x8, +-}; +- +-enum aice_target_endian { +- AICE_LITTLE_ENDIAN = 0, +- AICE_BIG_ENDIAN, +-}; +- +-enum aice_api_s { +- AICE_OPEN = 0x0, +- AICE_CLOSE, +- AICE_RESET, +- AICE_IDCODE, +- AICE_SET_JTAG_CLOCK, +- AICE_ASSERT_SRST, +- AICE_RUN, +- AICE_HALT, +- AICE_STEP, +- AICE_READ_REG, +- AICE_WRITE_REG, +- AICE_READ_REG_64, +- AICE_WRITE_REG_64, +- AICE_READ_MEM_UNIT, +- AICE_WRITE_MEM_UNIT, +- AICE_READ_MEM_BULK, +- AICE_WRITE_MEM_BULK, +- AICE_READ_DEBUG_REG, +- AICE_WRITE_DEBUG_REG, +- AICE_STATE, +- AICE_MEMORY_ACCESS, +- AICE_MEMORY_MODE, +- AICE_READ_TLB, +- AICE_CACHE_CTL, +- AICE_SET_RETRY_TIMES, +- AICE_PROGRAM_EDM, +- AICE_SET_COMMAND_MODE, +- AICE_EXECUTE, +- AICE_SET_CUSTOM_SRST_SCRIPT, +- AICE_SET_CUSTOM_TRST_SCRIPT, +- AICE_SET_CUSTOM_RESTART_SCRIPT, +- AICE_SET_COUNT_TO_CHECK_DBGER, +- AICE_SET_DATA_ENDIAN, +-}; +- +-enum aice_error_s { +- AICE_OK, +- AICE_ACK, +- AICE_ERROR, +-}; +- +-enum aice_cache_ctl_type { +- AICE_CACHE_CTL_L1D_INVALALL = 0, +- AICE_CACHE_CTL_L1D_VA_INVAL, +- AICE_CACHE_CTL_L1D_WBALL, +- AICE_CACHE_CTL_L1D_VA_WB, +- AICE_CACHE_CTL_L1I_INVALALL, +- AICE_CACHE_CTL_L1I_VA_INVAL, +-}; +- +-enum aice_command_mode { +- AICE_COMMAND_MODE_NORMAL, +- AICE_COMMAND_MODE_PACK, +- AICE_COMMAND_MODE_BATCH, +-}; +- +-struct aice_port_param_s { +- /** */ +- const char *device_desc; +- /** */ +- uint16_t vid; +- /** */ +- uint16_t pid; +- /** */ +- char *adapter_name; +-}; +- +-struct aice_port_s { +- /** */ +- uint32_t coreid; +- /** */ +- const struct aice_port *port; +-}; +- +-/** */ +-extern struct aice_port_api_s aice_usb_layout_api; +- +-/** */ +-struct aice_port_api_s { +- /** */ +- int (*open)(struct aice_port_param_s *param); +- /** */ +- int (*close)(void); +- /** */ +- int (*reset)(void); +- /** */ +- int (*idcode)(uint32_t *idcode, uint8_t *num_of_idcode); +- /** */ +- int (*set_jtag_clock)(uint32_t a_clock); +- /** */ +- int (*assert_srst)(uint32_t coreid, enum aice_srst_type_s srst); +- /** */ +- int (*run)(uint32_t coreid); +- /** */ +- int (*halt)(uint32_t coreid); +- /** */ +- int (*step)(uint32_t coreid); +- /** */ +- int (*read_reg)(uint32_t coreid, uint32_t num, uint32_t *val); +- /** */ +- int (*write_reg)(uint32_t coreid, uint32_t num, uint32_t val); +- /** */ +- int (*read_reg_64)(uint32_t coreid, uint32_t num, uint64_t *val); +- /** */ +- int (*write_reg_64)(uint32_t coreid, uint32_t num, uint64_t val); +- /** */ +- int (*read_mem_unit)(uint32_t coreid, uint32_t addr, uint32_t size, +- uint32_t count, uint8_t *buffer); +- /** */ +- int (*write_mem_unit)(uint32_t coreid, uint32_t addr, uint32_t size, +- uint32_t count, const uint8_t *buffer); +- /** */ +- int (*read_mem_bulk)(uint32_t coreid, uint32_t addr, uint32_t length, +- uint8_t *buffer); +- /** */ +- int (*write_mem_bulk)(uint32_t coreid, uint32_t addr, uint32_t length, +- const uint8_t *buffer); +- /** */ +- int (*read_debug_reg)(uint32_t coreid, uint32_t addr, uint32_t *val); +- /** */ +- int (*write_debug_reg)(uint32_t coreid, uint32_t addr, const uint32_t val); +- +- /** */ +- int (*state)(uint32_t coreid, enum aice_target_state_s *state); +- +- /** */ +- int (*memory_access)(uint32_t coreid, enum nds_memory_access a_access); +- /** */ +- int (*memory_mode)(uint32_t coreid, enum nds_memory_select mem_select); +- +- /** */ +- int (*read_tlb)(uint32_t coreid, target_addr_t virtual_address, target_addr_t *physical_address); +- +- /** */ +- int (*cache_ctl)(uint32_t coreid, uint32_t subtype, uint32_t address); +- +- /** */ +- int (*set_retry_times)(uint32_t a_retry_times); +- +- /** */ +- int (*program_edm)(uint32_t coreid, char *command_sequence); +- +- /** */ +- int (*set_command_mode)(enum aice_command_mode command_mode); +- +- /** */ +- int (*execute)(uint32_t coreid, uint32_t *instructions, uint32_t instruction_num); +- +- /** */ +- int (*set_custom_srst_script)(const char *script); +- +- /** */ +- int (*set_custom_trst_script)(const char *script); +- +- /** */ +- int (*set_custom_restart_script)(const char *script); +- +- /** */ +- int (*set_count_to_check_dbger)(uint32_t count_to_check); +- +- /** */ +- int (*set_data_endian)(uint32_t coreid, enum aice_target_endian target_data_endian); +- +- /** */ +- int (*profiling)(uint32_t coreid, uint32_t interval, uint32_t iteration, +- uint32_t reg_no, uint32_t *samples, uint32_t *num_samples); +-}; +- +-#define AICE_PORT_UNKNOWN 0 +-#define AICE_PORT_AICE_USB 1 +-#define AICE_PORT_AICE_PIPE 2 +- +-/** */ +-struct aice_port { +- /** */ +- const char *name; +- /** */ +- int type; +- /** */ +- struct aice_port_api_s *const api; +-}; +- +-/** */ +-const struct aice_port *aice_port_get_list(void); +- +-#endif /* OPENOCD_JTAG_AICE_AICE_PORT_H */ +diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c +deleted file mode 100644 +index 49f899ddc..000000000 +--- a/src/jtag/aice/aice_transport.c ++++ /dev/null +@@ -1,432 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-/* project specific includes */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* */ +-static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi, +- struct jtag_tap *tap) +-{ +- jim_wide w; +- int e = jim_getopt_wide(goi, &w); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", +- n->name); +- return e; +- } +- +- unsigned expected_len = sizeof(uint32_t) * tap->expected_ids_cnt; +- uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t)); +- if (!new_expected_ids) { +- Jim_SetResultFormatted(goi->interp, "no memory"); +- return JIM_ERR; +- } +- +- assert(tap->expected_ids); +- memcpy(new_expected_ids, tap->expected_ids, expected_len); +- +- new_expected_ids[tap->expected_ids_cnt] = w; +- +- free(tap->expected_ids); +- tap->expected_ids = new_expected_ids; +- tap->expected_ids_cnt++; +- +- return JIM_OK; +-} +- +-#define NTAP_OPT_EXPECTED_ID 0 +- +-/* */ +-static int jim_aice_newtap_cmd(struct jim_getopt_info *goi) +-{ +- struct jtag_tap *tap; +- int x; +- int e; +- struct jim_nvp *n; +- char *cp; +- const struct jim_nvp opts[] = { +- {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID}, +- {.name = NULL, .value = -1}, +- }; +- +- tap = calloc(1, sizeof(struct jtag_tap)); +- if (!tap) { +- Jim_SetResultFormatted(goi->interp, "no memory"); +- return JIM_ERR; +- } +- +- /* +- * we expect CHIP + TAP + OPTIONS +- * */ +- if (goi->argc < 3) { +- Jim_SetResultFormatted(goi->interp, +- "Missing CHIP TAP OPTIONS ...."); +- free(tap); +- return JIM_ERR; +- } +- +- const char *tmp; +- jim_getopt_string(goi, &tmp, NULL); +- tap->chip = strdup(tmp); +- +- jim_getopt_string(goi, &tmp, NULL); +- tap->tapname = strdup(tmp); +- +- /* name + dot + name + null */ +- x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1; +- cp = malloc(x); +- sprintf(cp, "%s.%s", tap->chip, tap->tapname); +- tap->dotted_name = cp; +- +- LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", +- tap->chip, tap->tapname, tap->dotted_name, goi->argc); +- +- while (goi->argc) { +- e = jim_getopt_nvp(goi, opts, &n); +- if (e != JIM_OK) { +- jim_getopt_nvp_unknown(goi, opts, 0); +- free(cp); +- free(tap); +- return e; +- } +- LOG_DEBUG("Processing option: %s", n->name); +- switch (n->value) { +- case NTAP_OPT_EXPECTED_ID: +- e = jim_newtap_expected_id(n, goi, tap); +- if (e != JIM_OK) { +- free(cp); +- free(tap); +- return e; +- } +- break; +- } /* switch (n->value) */ +- } /* while (goi->argc) */ +- +- /* default is enabled-after-reset */ +- tap->enabled = !tap->disabled_after_reset; +- +- jtag_tap_init(tap); +- return JIM_OK; +-} +- +-/* */ +-static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- return jim_aice_newtap_cmd(&goi); +-} +- +-/* */ +-COMMAND_HANDLER(handle_aice_init_command) +-{ +- if (CMD_ARGC != 0) +- return ERROR_COMMAND_SYNTAX_ERROR; +- +- static bool jtag_initialized; +- if (jtag_initialized) { +- LOG_INFO("'jtag init' has already been called"); +- return ERROR_OK; +- } +- jtag_initialized = true; +- +- LOG_DEBUG("Initializing jtag devices..."); +- return jtag_init(CMD_CTX); +-} +- +-COMMAND_HANDLER(handle_scan_chain_command) +-{ +- struct jtag_tap *tap; +- char expected_id[12]; +- +- aice_scan_jtag_chain(); +- tap = jtag_all_taps(); +- command_print(CMD, +- " TapName Enabled IdCode Expected IrLen IrCap IrMask"); +- command_print(CMD, +- "-- ------------------- -------- ---------- ---------- ----- ----- ------"); +- +- while (tap) { +- uint32_t expected, expected_mask, ii; +- +- snprintf(expected_id, sizeof(expected_id), "0x%08x", +- (unsigned)((tap->expected_ids_cnt > 0) +- ? tap->expected_ids[0] +- : 0)); +- if (tap->ignore_version) +- expected_id[2] = '*'; +- +- expected = buf_get_u32(tap->expected, 0, tap->ir_length); +- expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length); +- +- command_print(CMD, +- "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x", +- tap->abs_chain_position, +- tap->dotted_name, +- tap->enabled ? 'Y' : 'n', +- (unsigned int)(tap->idcode), +- expected_id, +- (unsigned int)(tap->ir_length), +- (unsigned int)(expected), +- (unsigned int)(expected_mask)); +- +- for (ii = 1; ii < tap->expected_ids_cnt; ii++) { +- snprintf(expected_id, sizeof(expected_id), "0x%08x", +- (unsigned) tap->expected_ids[ii]); +- if (tap->ignore_version) +- expected_id[2] = '*'; +- +- command_print(CMD, +- " %s", +- expected_id); +- } +- +- tap = tap->next_tap; +- } +- +- return ERROR_OK; +-} +- +-static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- LOG_DEBUG("No implement: jim_aice_arp_init"); +- +- return JIM_OK; +-} +- +-/* */ +-static int aice_init_reset(struct command_context *cmd_ctx) +-{ +- LOG_DEBUG("Initializing with hard TRST+SRST reset"); +- +- int retval; +- enum reset_types jtag_reset_config = jtag_get_reset_config(); +- +- jtag_add_reset(1, 0); /* TAP_RESET */ +- if (jtag_reset_config & RESET_HAS_SRST) { +- jtag_add_reset(1, 1); +- if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) +- jtag_add_reset(0, 1); +- } +- jtag_add_reset(0, 0); +- retval = jtag_execute_queue(); +- if (retval != ERROR_OK) +- return retval; +- +- return ERROR_OK; +-} +- +-/* */ +-static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- int e = ERROR_OK; +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- if (goi.argc != 0) { +- Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)"); +- return JIM_ERR; +- } +- struct command_context *context = current_command_context(interp); +- e = aice_init_reset(context); +- +- if (e != ERROR_OK) { +- Jim_Obj *obj = Jim_NewIntObj(goi.interp, e); +- Jim_SetResultFormatted(goi.interp, "error: %#s", obj); +- return JIM_ERR; +- } +- return JIM_OK; +-} +- +-static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +-{ +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- if (goi.argc != 0) { +- Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters"); +- return JIM_ERR; +- } +- Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0)); +- struct jtag_tap *tap; +- +- for (tap = jtag_all_taps(); tap; tap = tap->next_tap) +- Jim_ListAppendElement(goi.interp, +- Jim_GetResult(goi.interp), +- Jim_NewStringObj(goi.interp, +- tap->dotted_name, -1)); +- +- return JIM_OK; +-} +- +-/* */ +-static const struct command_registration aice_transport_jtag_subcommand_handlers[] = { +- { +- .name = "init", +- .mode = COMMAND_ANY, +- .handler = handle_aice_init_command, +- .help = "initialize jtag scan chain", +- .usage = "" +- }, +- { +- .name = "arp_init", +- .mode = COMMAND_ANY, +- .jim_handler = jim_aice_arp_init, +- .help = "Validates JTAG scan chain against the list of " +- "declared TAPs.", +- }, +- { +- .name = "arp_init-reset", +- .mode = COMMAND_ANY, +- .jim_handler = jim_aice_arp_init_reset, +- .help = "Uses TRST and SRST to try resetting everything on " +- "the JTAG scan chain, then performs 'jtag arp_init'." +- }, +- { +- .name = "newtap", +- .mode = COMMAND_CONFIG, +- .jim_handler = jim_aice_newtap, +- .help = "Create a new TAP instance named basename.tap_type, " +- "and appends it to the scan chain.", +- .usage = "basename tap_type ['-expected_id' number]" +- }, +- { +- .name = "tapisenabled", +- .mode = COMMAND_EXEC, +- .jim_handler = jim_jtag_tap_enabler, +- .help = "Returns a Tcl boolean (0/1) indicating whether " +- "the TAP is enabled (1) or not (0).", +- .usage = "tap_name", +- }, +- { +- .name = "tapenable", +- .mode = COMMAND_EXEC, +- .jim_handler = jim_jtag_tap_enabler, +- .help = "Try to enable the specified TAP using the " +- "'tap-enable' TAP event.", +- .usage = "tap_name", +- }, +- { +- .name = "tapdisable", +- .mode = COMMAND_EXEC, +- .jim_handler = jim_jtag_tap_enabler, +- .help = "Try to disable the specified TAP using the " +- "'tap-disable' TAP event.", +- .usage = "tap_name", +- }, +- { +- .name = "configure", +- .mode = COMMAND_ANY, +- .jim_handler = jim_jtag_configure, +- .help = "Provide a Tcl handler for the specified " +- "TAP event.", +- .usage = "tap_name '-event' event_name handler", +- }, +- { +- .name = "cget", +- .mode = COMMAND_EXEC, +- .jim_handler = jim_jtag_configure, +- .help = "Return any Tcl handler for the specified " +- "TAP event.", +- .usage = "tap_name '-event' event_name", +- }, +- { +- .name = "names", +- .mode = COMMAND_ANY, +- .jim_handler = jim_aice_names, +- .help = "Returns list of all JTAG tap names.", +- }, +- { +- .name = "scan_chain", +- .handler = handle_scan_chain_command, +- .mode = COMMAND_ANY, +- .help = "print current scan chain configuration", +- .usage = "" +- }, +- +- COMMAND_REGISTRATION_DONE +-}; +- +-/* */ +-static const struct command_registration aice_transport_command_handlers[] = { +- { +- .name = "jtag", +- .mode = COMMAND_ANY, +- .usage = "", +- .chain = aice_transport_jtag_subcommand_handlers, +- }, +- COMMAND_REGISTRATION_DONE +- +-}; +- +-/* */ +-static int aice_transport_register_commands(struct command_context *cmd_ctx) +-{ +- return register_commands(cmd_ctx, NULL, aice_transport_command_handlers); +-} +- +-/* */ +-static int aice_transport_init(struct command_context *cmd_ctx) +-{ +- LOG_DEBUG("aice_transport_init"); +- struct target *t = get_current_target(cmd_ctx); +- struct transport *transport; +- +- if (!t) { +- LOG_ERROR("no current target"); +- return ERROR_FAIL; +- } +- +- transport = get_current_transport(); +- +- if (!transport) { +- LOG_ERROR("no transport selected"); +- return ERROR_FAIL; +- } +- +- LOG_DEBUG("current transport %s", transport->name); +- +- return aice_init_targets(); +-} +- +-/* */ +-static int aice_transport_select(struct command_context *ctx) +-{ +- LOG_DEBUG("aice_transport_select"); +- +- int retval; +- +- retval = aice_transport_register_commands(ctx); +- +- if (retval != ERROR_OK) +- return retval; +- +- return ERROR_OK; +-} +- +-static struct transport aice_jtag_transport = { +- .name = "aice_jtag", +- .select = aice_transport_select, +- .init = aice_transport_init, +-}; +- +-const char *aice_transports[] = { "aice_jtag", NULL }; +- +-static void aice_constructor(void) __attribute__((constructor)); +-static void aice_constructor(void) +-{ +- transport_register(&aice_jtag_transport); +-} +diff --git a/src/jtag/aice/aice_transport.h b/src/jtag/aice/aice_transport.h +deleted file mode 100644 +index b00003198..000000000 +--- a/src/jtag/aice/aice_transport.h ++++ /dev/null +@@ -1,13 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_JTAG_AICE_AICE_TRANSPORT_H +-#define OPENOCD_JTAG_AICE_AICE_TRANSPORT_H +- +-extern const char *aice_transports[]; +- +-#endif /* OPENOCD_JTAG_AICE_AICE_TRANSPORT_H */ +diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c +deleted file mode 100644 +index b5d0f0b6e..000000000 +--- a/src/jtag/aice/aice_usb.c ++++ /dev/null +@@ -1,4099 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "aice_usb.h" +- +- +-/* Global USB buffers */ +-static uint8_t usb_in_buffer[AICE_IN_BUFFER_SIZE]; +-static uint8_t usb_out_buffer[AICE_OUT_BUFFER_SIZE]; +-static uint32_t jtag_clock; +-static struct aice_usb_handler_s aice_handler; +-/* AICE max retry times. If AICE command timeout, retry it. */ +-static int aice_max_retry_times = 50; +-/* Default endian is little endian. */ +-static enum aice_target_endian data_endian; +- +-/* Constants for AICE command format length */ +-#define AICE_FORMAT_HTDA (3) +-#define AICE_FORMAT_HTDC (7) +-#define AICE_FORMAT_HTDMA (4) +-#define AICE_FORMAT_HTDMB (8) +-#define AICE_FORMAT_HTDMC (8) +-#define AICE_FORMAT_HTDMD (12) +-#define AICE_FORMAT_DTHA (6) +-#define AICE_FORMAT_DTHB (2) +-#define AICE_FORMAT_DTHMA (8) +-#define AICE_FORMAT_DTHMB (4) +- +-/* Constants for AICE command */ +-#define AICE_CMD_SCAN_CHAIN 0x00 +-#define AICE_CMD_T_READ_MISC 0x20 +-#define AICE_CMD_T_READ_EDMSR 0x21 +-#define AICE_CMD_T_READ_DTR 0x22 +-#define AICE_CMD_T_READ_MEM_B 0x24 +-#define AICE_CMD_T_READ_MEM_H 0x25 +-#define AICE_CMD_T_READ_MEM 0x26 +-#define AICE_CMD_T_FASTREAD_MEM 0x27 +-#define AICE_CMD_T_WRITE_MISC 0x28 +-#define AICE_CMD_T_WRITE_EDMSR 0x29 +-#define AICE_CMD_T_WRITE_DTR 0x2A +-#define AICE_CMD_T_WRITE_DIM 0x2B +-#define AICE_CMD_T_WRITE_MEM_B 0x2C +-#define AICE_CMD_T_WRITE_MEM_H 0x2D +-#define AICE_CMD_T_WRITE_MEM 0x2E +-#define AICE_CMD_T_FASTWRITE_MEM 0x2F +-#define AICE_CMD_T_EXECUTE 0x3E +-#define AICE_CMD_READ_CTRL 0x50 +-#define AICE_CMD_WRITE_CTRL 0x51 +-#define AICE_CMD_BATCH_BUFFER_READ 0x60 +-#define AICE_CMD_READ_DTR_TO_BUFFER 0x61 +-#define AICE_CMD_BATCH_BUFFER_WRITE 0x68 +-#define AICE_CMD_WRITE_DTR_FROM_BUFFER 0x69 +- +-/***************************************************************************/ +-/* AICE commands' pack/unpack functions */ +-static void aice_pack_htda(uint8_t cmd_code, uint8_t extra_word_length, +- uint32_t address) +-{ +- usb_out_buffer[0] = cmd_code; +- usb_out_buffer[1] = extra_word_length; +- usb_out_buffer[2] = (uint8_t)(address & 0xFF); +-} +- +-static void aice_pack_htdc(uint8_t cmd_code, uint8_t extra_word_length, +- uint32_t address, uint32_t word, enum aice_target_endian access_endian) +-{ +- usb_out_buffer[0] = cmd_code; +- usb_out_buffer[1] = extra_word_length; +- usb_out_buffer[2] = (uint8_t)(address & 0xFF); +- if (access_endian == AICE_BIG_ENDIAN) { +- usb_out_buffer[6] = (uint8_t)((word >> 24) & 0xFF); +- usb_out_buffer[5] = (uint8_t)((word >> 16) & 0xFF); +- usb_out_buffer[4] = (uint8_t)((word >> 8) & 0xFF); +- usb_out_buffer[3] = (uint8_t)(word & 0xFF); +- } else { +- usb_out_buffer[3] = (uint8_t)((word >> 24) & 0xFF); +- usb_out_buffer[4] = (uint8_t)((word >> 16) & 0xFF); +- usb_out_buffer[5] = (uint8_t)((word >> 8) & 0xFF); +- usb_out_buffer[6] = (uint8_t)(word & 0xFF); +- } +-} +- +-static void aice_pack_htdma(uint8_t cmd_code, uint8_t target_id, +- uint8_t extra_word_length, uint32_t address) +-{ +- usb_out_buffer[0] = cmd_code; +- usb_out_buffer[1] = target_id; +- usb_out_buffer[2] = extra_word_length; +- usb_out_buffer[3] = (uint8_t)(address & 0xFF); +-} +- +-static void aice_pack_htdmb(uint8_t cmd_code, uint8_t target_id, +- uint8_t extra_word_length, uint32_t address) +-{ +- usb_out_buffer[0] = cmd_code; +- usb_out_buffer[1] = target_id; +- usb_out_buffer[2] = extra_word_length; +- usb_out_buffer[3] = 0; +- usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); +- usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); +- usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); +- usb_out_buffer[7] = (uint8_t)(address & 0xFF); +-} +- +-static void aice_pack_htdmc(uint8_t cmd_code, uint8_t target_id, +- uint8_t extra_word_length, uint32_t address, uint32_t word, +- enum aice_target_endian access_endian) +-{ +- usb_out_buffer[0] = cmd_code; +- usb_out_buffer[1] = target_id; +- usb_out_buffer[2] = extra_word_length; +- usb_out_buffer[3] = (uint8_t)(address & 0xFF); +- if (access_endian == AICE_BIG_ENDIAN) { +- usb_out_buffer[7] = (uint8_t)((word >> 24) & 0xFF); +- usb_out_buffer[6] = (uint8_t)((word >> 16) & 0xFF); +- usb_out_buffer[5] = (uint8_t)((word >> 8) & 0xFF); +- usb_out_buffer[4] = (uint8_t)(word & 0xFF); +- } else { +- usb_out_buffer[4] = (uint8_t)((word >> 24) & 0xFF); +- usb_out_buffer[5] = (uint8_t)((word >> 16) & 0xFF); +- usb_out_buffer[6] = (uint8_t)((word >> 8) & 0xFF); +- usb_out_buffer[7] = (uint8_t)(word & 0xFF); +- } +-} +- +-static void aice_pack_htdmc_multiple_data(uint8_t cmd_code, uint8_t target_id, +- uint8_t extra_word_length, uint32_t address, uint32_t *word, +- uint8_t num_of_words, enum aice_target_endian access_endian) +-{ +- usb_out_buffer[0] = cmd_code; +- usb_out_buffer[1] = target_id; +- usb_out_buffer[2] = extra_word_length; +- usb_out_buffer[3] = (uint8_t)(address & 0xFF); +- +- uint8_t i; +- for (i = 0 ; i < num_of_words ; i++, word++) { +- if (access_endian == AICE_BIG_ENDIAN) { +- usb_out_buffer[7 + i * 4] = (uint8_t)((*word >> 24) & 0xFF); +- usb_out_buffer[6 + i * 4] = (uint8_t)((*word >> 16) & 0xFF); +- usb_out_buffer[5 + i * 4] = (uint8_t)((*word >> 8) & 0xFF); +- usb_out_buffer[4 + i * 4] = (uint8_t)(*word & 0xFF); +- } else { +- usb_out_buffer[4 + i * 4] = (uint8_t)((*word >> 24) & 0xFF); +- usb_out_buffer[5 + i * 4] = (uint8_t)((*word >> 16) & 0xFF); +- usb_out_buffer[6 + i * 4] = (uint8_t)((*word >> 8) & 0xFF); +- usb_out_buffer[7 + i * 4] = (uint8_t)(*word & 0xFF); +- } +- } +-} +- +-static void aice_pack_htdmd(uint8_t cmd_code, uint8_t target_id, +- uint8_t extra_word_length, uint32_t address, uint32_t word, +- enum aice_target_endian access_endian) +-{ +- usb_out_buffer[0] = cmd_code; +- usb_out_buffer[1] = target_id; +- usb_out_buffer[2] = extra_word_length; +- usb_out_buffer[3] = 0; +- usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); +- usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); +- usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); +- usb_out_buffer[7] = (uint8_t)(address & 0xFF); +- if (access_endian == AICE_BIG_ENDIAN) { +- usb_out_buffer[11] = (uint8_t)((word >> 24) & 0xFF); +- usb_out_buffer[10] = (uint8_t)((word >> 16) & 0xFF); +- usb_out_buffer[9] = (uint8_t)((word >> 8) & 0xFF); +- usb_out_buffer[8] = (uint8_t)(word & 0xFF); +- } else { +- usb_out_buffer[8] = (uint8_t)((word >> 24) & 0xFF); +- usb_out_buffer[9] = (uint8_t)((word >> 16) & 0xFF); +- usb_out_buffer[10] = (uint8_t)((word >> 8) & 0xFF); +- usb_out_buffer[11] = (uint8_t)(word & 0xFF); +- } +-} +- +-static void aice_pack_htdmd_multiple_data(uint8_t cmd_code, uint8_t target_id, +- uint8_t extra_word_length, uint32_t address, const uint8_t *word, +- enum aice_target_endian access_endian) +-{ +- usb_out_buffer[0] = cmd_code; +- usb_out_buffer[1] = target_id; +- usb_out_buffer[2] = extra_word_length; +- usb_out_buffer[3] = 0; +- usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); +- usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); +- usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); +- usb_out_buffer[7] = (uint8_t)(address & 0xFF); +- +- uint32_t i; +- /* num_of_words may be over 0xFF, so use uint32_t */ +- uint32_t num_of_words = extra_word_length + 1; +- +- for (i = 0 ; i < num_of_words ; i++, word += 4) { +- if (access_endian == AICE_BIG_ENDIAN) { +- usb_out_buffer[11 + i * 4] = word[3]; +- usb_out_buffer[10 + i * 4] = word[2]; +- usb_out_buffer[9 + i * 4] = word[1]; +- usb_out_buffer[8 + i * 4] = word[0]; +- } else { +- usb_out_buffer[8 + i * 4] = word[3]; +- usb_out_buffer[9 + i * 4] = word[2]; +- usb_out_buffer[10 + i * 4] = word[1]; +- usb_out_buffer[11 + i * 4] = word[0]; +- } +- } +-} +- +-static void aice_unpack_dtha(uint8_t *cmd_ack_code, uint8_t *extra_word_length, +- uint32_t *word, enum aice_target_endian access_endian) +-{ +- *cmd_ack_code = usb_in_buffer[0]; +- *extra_word_length = usb_in_buffer[1]; +- +- if (access_endian == AICE_BIG_ENDIAN) { +- *word = (usb_in_buffer[5] << 24) | +- (usb_in_buffer[4] << 16) | +- (usb_in_buffer[3] << 8) | +- (usb_in_buffer[2]); +- } else { +- *word = (usb_in_buffer[2] << 24) | +- (usb_in_buffer[3] << 16) | +- (usb_in_buffer[4] << 8) | +- (usb_in_buffer[5]); +- } +-} +- +-static void aice_unpack_dtha_multiple_data(uint8_t *cmd_ack_code, +- uint8_t *extra_word_length, uint32_t *word, uint8_t num_of_words, +- enum aice_target_endian access_endian) +-{ +- *cmd_ack_code = usb_in_buffer[0]; +- *extra_word_length = usb_in_buffer[1]; +- +- uint8_t i; +- for (i = 0 ; i < num_of_words ; i++, word++) { +- if (access_endian == AICE_BIG_ENDIAN) { +- *word = (usb_in_buffer[5 + i * 4] << 24) | +- (usb_in_buffer[4 + i * 4] << 16) | +- (usb_in_buffer[3 + i * 4] << 8) | +- (usb_in_buffer[2 + i * 4]); +- } else { +- *word = (usb_in_buffer[2 + i * 4] << 24) | +- (usb_in_buffer[3 + i * 4] << 16) | +- (usb_in_buffer[4 + i * 4] << 8) | +- (usb_in_buffer[5 + i * 4]); +- } +- } +-} +- +-static void aice_unpack_dthb(uint8_t *cmd_ack_code, uint8_t *extra_word_length) +-{ +- *cmd_ack_code = usb_in_buffer[0]; +- *extra_word_length = usb_in_buffer[1]; +-} +- +-static void aice_unpack_dthma(uint8_t *cmd_ack_code, uint8_t *target_id, +- uint8_t *extra_word_length, uint32_t *word, +- enum aice_target_endian access_endian) +-{ +- *cmd_ack_code = usb_in_buffer[0]; +- *target_id = usb_in_buffer[1]; +- *extra_word_length = usb_in_buffer[2]; +- if (access_endian == AICE_BIG_ENDIAN) { +- *word = (usb_in_buffer[7] << 24) | +- (usb_in_buffer[6] << 16) | +- (usb_in_buffer[5] << 8) | +- (usb_in_buffer[4]); +- } else { +- *word = (usb_in_buffer[4] << 24) | +- (usb_in_buffer[5] << 16) | +- (usb_in_buffer[6] << 8) | +- (usb_in_buffer[7]); +- } +-} +- +-static void aice_unpack_dthma_multiple_data(uint8_t *cmd_ack_code, +- uint8_t *target_id, uint8_t *extra_word_length, uint8_t *word, +- enum aice_target_endian access_endian) +-{ +- *cmd_ack_code = usb_in_buffer[0]; +- *target_id = usb_in_buffer[1]; +- *extra_word_length = usb_in_buffer[2]; +- if (access_endian == AICE_BIG_ENDIAN) { +- word[0] = usb_in_buffer[4]; +- word[1] = usb_in_buffer[5]; +- word[2] = usb_in_buffer[6]; +- word[3] = usb_in_buffer[7]; +- } else { +- word[0] = usb_in_buffer[7]; +- word[1] = usb_in_buffer[6]; +- word[2] = usb_in_buffer[5]; +- word[3] = usb_in_buffer[4]; +- } +- word += 4; +- +- uint8_t i; +- for (i = 0; i < *extra_word_length; i++) { +- if (access_endian == AICE_BIG_ENDIAN) { +- word[0] = usb_in_buffer[8 + i * 4]; +- word[1] = usb_in_buffer[9 + i * 4]; +- word[2] = usb_in_buffer[10 + i * 4]; +- word[3] = usb_in_buffer[11 + i * 4]; +- } else { +- word[0] = usb_in_buffer[11 + i * 4]; +- word[1] = usb_in_buffer[10 + i * 4]; +- word[2] = usb_in_buffer[9 + i * 4]; +- word[3] = usb_in_buffer[8 + i * 4]; +- } +- word += 4; +- } +-} +- +-static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id, +- uint8_t *extra_word_length) +-{ +- *cmd_ack_code = usb_in_buffer[0]; +- *target_id = usb_in_buffer[1]; +- *extra_word_length = usb_in_buffer[2]; +-} +- +-/***************************************************************************/ +-/* End of AICE commands' pack/unpack functions */ +- +-/* calls the given usb_bulk_* function, allowing for the data to +- * trickle in with some timeouts */ +-static int usb_bulk_with_retries( +- int (*f)(struct libusb_device_handle *, int, char *, int, int, int *), +- struct libusb_device_handle *dev, int ep, +- char *bytes, int size, int timeout, int *transferred) +-{ +- int tries = 3, count = 0; +- +- while (tries && (count < size)) { +- int result, ret; +- +- ret = f(dev, ep, bytes + count, size - count, timeout, &result); +- if (ret == ERROR_OK) +- count += result; +- else if ((ret != ERROR_TIMEOUT_REACHED) || !--tries) +- return ret; +- } +- +- *transferred = count; +- return ERROR_OK; +-} +- +-static int wrap_usb_bulk_write(struct libusb_device_handle *dev, int ep, +- char *buff, int size, int timeout, int *transferred) +-{ +- +- /* usb_bulk_write() takes const char *buff */ +- jtag_libusb_bulk_write(dev, ep, buff, size, timeout, transferred); +- +- return 0; +-} +- +-static inline int usb_bulk_write_ex(struct libusb_device_handle *dev, int ep, +- char *bytes, int size, int timeout) +-{ +- int tr = 0; +- +- usb_bulk_with_retries(&wrap_usb_bulk_write, +- dev, ep, bytes, size, timeout, &tr); +- return tr; +-} +- +-static inline int usb_bulk_read_ex(struct libusb_device_handle *dev, int ep, +- char *bytes, int size, int timeout) +-{ +- int tr = 0; +- usb_bulk_with_retries(&jtag_libusb_bulk_read, +- dev, ep, bytes, size, timeout, &tr); +- return tr; +-} +- +-/* Write data from out_buffer to USB. */ +-static int aice_usb_write(uint8_t *out_buffer, int out_length) +-{ +- int result; +- +- if (out_length > AICE_OUT_BUFFER_SIZE) { +- LOG_ERROR("aice_write illegal out_length=%i (max=%i)", +- out_length, AICE_OUT_BUFFER_SIZE); +- return -1; +- } +- +- result = usb_bulk_write_ex(aice_handler.usb_handle, aice_handler.usb_write_ep, +- (char *)out_buffer, out_length, AICE_USB_TIMEOUT); +- +- LOG_DEBUG_IO("aice_usb_write, out_length = %i, result = %i", +- out_length, result); +- +- return result; +-} +- +-/* Read data from USB into in_buffer. */ +-static int aice_usb_read(uint8_t *in_buffer, int expected_size) +-{ +- int result = usb_bulk_read_ex(aice_handler.usb_handle, aice_handler.usb_read_ep, +- (char *)in_buffer, expected_size, AICE_USB_TIMEOUT); +- +- LOG_DEBUG_IO("aice_usb_read, result = %d", result); +- +- return result; +-} +- +-static uint8_t usb_out_packets_buffer[AICE_OUT_PACKETS_BUFFER_SIZE]; +-static uint8_t usb_in_packets_buffer[AICE_IN_PACKETS_BUFFER_SIZE]; +-static uint32_t usb_out_packets_buffer_length; +-static uint32_t usb_in_packets_buffer_length; +-static enum aice_command_mode aice_command_mode; +- +-static int aice_batch_buffer_write(uint8_t buf_index, const uint8_t *word, +- uint32_t num_of_words); +- +-static int aice_usb_packet_flush(void) +-{ +- if (usb_out_packets_buffer_length == 0) +- return 0; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- LOG_DEBUG("Flush usb packets (AICE_COMMAND_MODE_PACK)"); +- +- if (aice_usb_write(usb_out_packets_buffer, +- usb_out_packets_buffer_length) < 0) +- return ERROR_FAIL; +- +- if (aice_usb_read(usb_in_packets_buffer, +- usb_in_packets_buffer_length) < 0) +- return ERROR_FAIL; +- +- usb_out_packets_buffer_length = 0; +- usb_in_packets_buffer_length = 0; +- +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- LOG_DEBUG("Flush usb packets (AICE_COMMAND_MODE_BATCH)"); +- +- /* use BATCH_BUFFER_WRITE to fill command-batch-buffer */ +- if (aice_batch_buffer_write(AICE_BATCH_COMMAND_BUFFER_0, +- usb_out_packets_buffer, +- (usb_out_packets_buffer_length + 3) / 4) != ERROR_OK) +- return ERROR_FAIL; +- +- usb_out_packets_buffer_length = 0; +- usb_in_packets_buffer_length = 0; +- +- /* enable BATCH command */ +- aice_command_mode = AICE_COMMAND_MODE_NORMAL; +- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CTRL, 0x80000000) != ERROR_OK) +- return ERROR_FAIL; +- aice_command_mode = AICE_COMMAND_MODE_BATCH; +- +- /* wait 1 second (AICE bug, workaround) */ +- alive_sleep(1000); +- +- /* check status */ +- uint32_t i; +- uint32_t batch_status; +- +- i = 0; +- while (1) { +- int retval = aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status); +- if (retval != ERROR_OK) +- return retval; +- +- if (batch_status & 0x1) +- return ERROR_OK; +- else if (batch_status & 0xE) +- return ERROR_FAIL; +- +- if ((i % 30) == 0) +- keep_alive(); +- +- i++; +- } +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_packet_append(uint8_t *out_buffer, int out_length, int in_length) +-{ +- uint32_t max_packet_size = AICE_OUT_PACKETS_BUFFER_SIZE; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- max_packet_size = AICE_OUT_PACK_COMMAND_SIZE; +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- max_packet_size = AICE_OUT_BATCH_COMMAND_SIZE; +- } else { +- /* AICE_COMMAND_MODE_NORMAL */ +- if (aice_usb_packet_flush() != ERROR_OK) +- return ERROR_FAIL; +- } +- +- if (usb_out_packets_buffer_length + out_length > max_packet_size) +- if (aice_usb_packet_flush() != ERROR_OK) { +- LOG_DEBUG("Flush usb packets failed"); +- return ERROR_FAIL; +- } +- +- LOG_DEBUG("Append usb packets 0x%02x", out_buffer[0]); +- +- memcpy(usb_out_packets_buffer + usb_out_packets_buffer_length, out_buffer, out_length); +- usb_out_packets_buffer_length += out_length; +- usb_in_packets_buffer_length += in_length; +- +- return ERROR_OK; +-} +- +-/***************************************************************************/ +-/* AICE commands */ +-static int aice_reset_box(void) +-{ +- if (aice_write_ctrl(AICE_WRITE_CTRL_CLEAR_TIMEOUT_STATUS, 0x1) != ERROR_OK) +- return ERROR_FAIL; +- +- /* turn off FASTMODE */ +- uint32_t pin_status; +- if (aice_read_ctrl(AICE_READ_CTRL_GET_JTAG_PIN_STATUS, &pin_status) +- != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status & (~0x2)) +- != ERROR_OK) +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int aice_scan_chain(uint32_t *id_codes, uint8_t *num_of_ids) +-{ +- int retry_times = 0; +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- do { +- aice_pack_htda(AICE_CMD_SCAN_CHAIN, 0x0F, 0x0); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDA); +- +- LOG_DEBUG("SCAN_CHAIN, length: 0x0F"); +- +- /** TODO: modify receive length */ +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHA); +- if (result != AICE_FORMAT_DTHA) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHA, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- aice_unpack_dtha_multiple_data(&cmd_ack_code, num_of_ids, id_codes, +- 0x10, AICE_LITTLE_ENDIAN); +- +- if (cmd_ack_code != AICE_CMD_SCAN_CHAIN) { +- +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_SCAN_CHAIN, cmd_ack_code); +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- continue; +- } +- +- LOG_DEBUG("SCAN_CHAIN response, # of IDs: %" PRIu8, *num_of_ids); +- +- if (*num_of_ids == 0xFF) { +- LOG_ERROR("No target connected"); +- return ERROR_FAIL; +- } else if (*num_of_ids == AICE_MAX_NUM_CORE) { +- LOG_INFO("The ice chain over 16 targets"); +- } else { +- (*num_of_ids)++; +- } +- break; +- } while (1); +- +- return ERROR_OK; +-} +- +-int aice_read_ctrl(uint32_t address, uint32_t *data) +-{ +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- aice_pack_htda(AICE_CMD_READ_CTRL, 0, address); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDA); +- +- LOG_DEBUG("READ_CTRL, address: 0x%" PRIx32, address); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHA); +- if (result != AICE_FORMAT_DTHA) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHA, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- aice_unpack_dtha(&cmd_ack_code, &extra_length, data, AICE_LITTLE_ENDIAN); +- +- LOG_DEBUG("READ_CTRL response, data: 0x%" PRIx32, *data); +- +- if (cmd_ack_code != AICE_CMD_READ_CTRL) { +- LOG_ERROR("aice command error (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_READ_CTRL, cmd_ack_code); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-int aice_write_ctrl(uint32_t address, uint32_t data) +-{ +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdc(AICE_CMD_WRITE_CTRL, 0, address, data, AICE_LITTLE_ENDIAN); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDC, +- AICE_FORMAT_DTHB); +- } +- +- aice_pack_htdc(AICE_CMD_WRITE_CTRL, 0, address, data, AICE_LITTLE_ENDIAN); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDC); +- +- LOG_DEBUG("WRITE_CTRL, address: 0x%" PRIx32 ", data: 0x%" PRIx32, address, data); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHB); +- if (result != AICE_FORMAT_DTHB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- aice_unpack_dthb(&cmd_ack_code, &extra_length); +- +- LOG_DEBUG("WRITE_CTRL response"); +- +- if (cmd_ack_code != AICE_CMD_WRITE_CTRL) { +- LOG_ERROR("aice command error (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_WRITE_CTRL, cmd_ack_code); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_read_dtr(uint8_t target_id, uint32_t *data) +-{ +- int retry_times = 0; +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- do { +- aice_pack_htdma(AICE_CMD_T_READ_DTR, target_id, 0, 0); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); +- +- LOG_DEBUG("READ_DTR, COREID: %" PRIu8, target_id); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); +- if (result != AICE_FORMAT_DTHMA) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMA, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, +- data, AICE_LITTLE_ENDIAN); +- +- if (cmd_ack_code == AICE_CMD_T_READ_DTR) { +- LOG_DEBUG("READ_DTR response, data: 0x%" PRIx32, *data); +- break; +- } else { +- +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_READ_DTR, cmd_ack_code); +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_read_dtr_to_buffer(uint8_t target_id, uint32_t buffer_idx) +-{ +- int retry_times = 0; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdma(AICE_CMD_READ_DTR_TO_BUFFER, target_id, 0, buffer_idx); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMA, +- AICE_FORMAT_DTHMB); +- } +- +- do { +- aice_pack_htdma(AICE_CMD_READ_DTR_TO_BUFFER, target_id, 0, buffer_idx); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); +- +- LOG_DEBUG("READ_DTR_TO_BUFFER, COREID: %" PRIu8, target_id); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_READ_DTR_TO_BUFFER) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_READ_DTR_TO_BUFFER, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_write_dtr(uint8_t target_id, uint32_t data) +-{ +- int retry_times = 0; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdmc(AICE_CMD_T_WRITE_DTR, target_id, 0, 0, data, AICE_LITTLE_ENDIAN); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, +- AICE_FORMAT_DTHMB); +- } +- +- do { +- aice_pack_htdmc(AICE_CMD_T_WRITE_DTR, target_id, 0, 0, data, AICE_LITTLE_ENDIAN); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); +- +- LOG_DEBUG("WRITE_DTR, COREID: %" PRIu8 ", data: 0x%" PRIx32, target_id, data); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_T_WRITE_DTR) { +- LOG_DEBUG("WRITE_DTR response"); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_WRITE_DTR, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_write_dtr_from_buffer(uint8_t target_id, uint32_t buffer_idx) +-{ +- int retry_times = 0; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdma(AICE_CMD_WRITE_DTR_FROM_BUFFER, target_id, 0, buffer_idx); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMA, +- AICE_FORMAT_DTHMB); +- } +- +- do { +- aice_pack_htdma(AICE_CMD_WRITE_DTR_FROM_BUFFER, target_id, 0, buffer_idx); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); +- +- LOG_DEBUG("WRITE_DTR_FROM_BUFFER, COREID: %" PRIu8 "", target_id); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_WRITE_DTR_FROM_BUFFER) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_WRITE_DTR_FROM_BUFFER, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_read_misc(uint8_t target_id, uint32_t address, uint32_t *data) +-{ +- int retry_times = 0; +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- do { +- aice_pack_htdma(AICE_CMD_T_READ_MISC, target_id, 0, address); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); +- +- LOG_DEBUG("READ_MISC, COREID: %" PRIu8 ", address: 0x%" PRIx32, target_id, address); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); +- if (result != AICE_FORMAT_DTHMA) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMA, result); +- return ERROR_AICE_DISCONNECT; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, +- data, AICE_LITTLE_ENDIAN); +- +- if (cmd_ack_code == AICE_CMD_T_READ_MISC) { +- LOG_DEBUG("READ_MISC response, data: 0x%" PRIx32, *data); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_READ_MISC, cmd_ack_code); +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_write_misc(uint8_t target_id, uint32_t address, uint32_t data) +-{ +- int retry_times = 0; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdmc(AICE_CMD_T_WRITE_MISC, target_id, 0, address, data, +- AICE_LITTLE_ENDIAN); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, +- AICE_FORMAT_DTHMB); +- } +- +- do { +- aice_pack_htdmc(AICE_CMD_T_WRITE_MISC, target_id, 0, address, +- data, AICE_LITTLE_ENDIAN); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); +- +- LOG_DEBUG("WRITE_MISC, COREID: %" PRIu8 ", address: 0x%" PRIx32 ", data: 0x%" PRIx32, +- target_id, address, data); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_T_WRITE_MISC) { +- LOG_DEBUG("WRITE_MISC response"); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_WRITE_MISC, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_read_edmsr(uint8_t target_id, uint32_t address, uint32_t *data) +-{ +- int retry_times = 0; +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- do { +- aice_pack_htdma(AICE_CMD_T_READ_EDMSR, target_id, 0, address); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); +- +- LOG_DEBUG("READ_EDMSR, COREID: %" PRIu8 ", address: 0x%" PRIx32, target_id, address); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); +- if (result != AICE_FORMAT_DTHMA) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMA, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, +- data, AICE_LITTLE_ENDIAN); +- +- if (cmd_ack_code == AICE_CMD_T_READ_EDMSR) { +- LOG_DEBUG("READ_EDMSR response, data: 0x%" PRIx32, *data); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_READ_EDMSR, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_write_edmsr(uint8_t target_id, uint32_t address, uint32_t data) +-{ +- int retry_times = 0; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdmc(AICE_CMD_T_WRITE_EDMSR, target_id, 0, address, data, +- AICE_LITTLE_ENDIAN); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, +- AICE_FORMAT_DTHMB); +- } +- +- do { +- aice_pack_htdmc(AICE_CMD_T_WRITE_EDMSR, target_id, 0, address, +- data, AICE_LITTLE_ENDIAN); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); +- +- LOG_DEBUG("WRITE_EDMSR, COREID: %" PRIu8 ", address: 0x%" PRIx32 ", data: 0x%" PRIx32, +- target_id, address, data); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_T_WRITE_EDMSR) { +- LOG_DEBUG("WRITE_EDMSR response"); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_WRITE_EDMSR, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_switch_to_big_endian(uint32_t *word, uint8_t num_of_words) +-{ +- uint32_t tmp; +- +- for (uint8_t i = 0 ; i < num_of_words ; i++) { +- tmp = ((word[i] >> 24) & 0x000000FF) | +- ((word[i] >> 8) & 0x0000FF00) | +- ((word[i] << 8) & 0x00FF0000) | +- ((word[i] << 24) & 0xFF000000); +- word[i] = tmp; +- } +- +- return ERROR_OK; +-} +- +-static int aice_write_dim(uint8_t target_id, uint32_t *word, uint8_t num_of_words) +-{ +- uint32_t big_endian_word[4]; +- int retry_times = 0; +- +- /** instruction is big-endian */ +- memcpy(big_endian_word, word, sizeof(big_endian_word)); +- aice_switch_to_big_endian(big_endian_word, num_of_words); +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdmc_multiple_data(AICE_CMD_T_WRITE_DIM, target_id, +- num_of_words - 1, 0, big_endian_word, num_of_words, +- AICE_LITTLE_ENDIAN); +- return aice_usb_packet_append(usb_out_buffer, +- AICE_FORMAT_HTDMC + (num_of_words - 1) * 4, +- AICE_FORMAT_DTHMB); +- } +- +- do { +- aice_pack_htdmc_multiple_data(AICE_CMD_T_WRITE_DIM, target_id, num_of_words - 1, 0, +- big_endian_word, num_of_words, AICE_LITTLE_ENDIAN); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC + (num_of_words - 1) * 4); +- +- LOG_DEBUG("WRITE_DIM, COREID: %" PRIu8 +- ", data: 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32, +- target_id, +- big_endian_word[0], +- big_endian_word[1], +- big_endian_word[2], +- big_endian_word[3]); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- +- if (cmd_ack_code == AICE_CMD_T_WRITE_DIM) { +- LOG_DEBUG("WRITE_DIM response"); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_WRITE_DIM, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_do_execute(uint8_t target_id) +-{ +- int retry_times = 0; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdmc(AICE_CMD_T_EXECUTE, target_id, 0, 0, 0, AICE_LITTLE_ENDIAN); +- return aice_usb_packet_append(usb_out_buffer, +- AICE_FORMAT_HTDMC, +- AICE_FORMAT_DTHMB); +- } +- +- do { +- aice_pack_htdmc(AICE_CMD_T_EXECUTE, target_id, 0, 0, 0, AICE_LITTLE_ENDIAN); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); +- +- LOG_DEBUG("EXECUTE, COREID: %" PRIu8 "", target_id); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_T_EXECUTE) { +- LOG_DEBUG("EXECUTE response"); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_EXECUTE, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_write_mem_b(uint8_t target_id, uint32_t address, uint32_t data) +-{ +- int retry_times = 0; +- +- LOG_DEBUG("WRITE_MEM_B, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, +- target_id, +- address, +- data); +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) { +- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_B, target_id, 0, address, +- data & 0x000000FF, data_endian); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, +- AICE_FORMAT_DTHMB); +- } else { +- do { +- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_B, target_id, 0, +- address, data & 0x000000FF, data_endian); +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_T_WRITE_MEM_B) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_WRITE_MEM_B, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- } +- +- return ERROR_OK; +-} +- +-static int aice_write_mem_h(uint8_t target_id, uint32_t address, uint32_t data) +-{ +- int retry_times = 0; +- +- LOG_DEBUG("WRITE_MEM_H, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, +- target_id, +- address, +- data); +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) { +- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_H, target_id, 0, +- (address >> 1) & 0x7FFFFFFF, data & 0x0000FFFF, data_endian); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, +- AICE_FORMAT_DTHMB); +- } else { +- do { +- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_H, target_id, 0, +- (address >> 1) & 0x7FFFFFFF, data & 0x0000FFFF, data_endian); +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_T_WRITE_MEM_H) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_WRITE_MEM_H, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- } +- +- return ERROR_OK; +-} +- +-static int aice_write_mem(uint8_t target_id, uint32_t address, uint32_t data) +-{ +- int retry_times = 0; +- +- LOG_DEBUG("WRITE_MEM, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, +- target_id, +- address, +- data); +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) { +- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM, target_id, 0, +- (address >> 2) & 0x3FFFFFFF, data, data_endian); +- return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, +- AICE_FORMAT_DTHMB); +- } else { +- do { +- aice_pack_htdmd(AICE_CMD_T_WRITE_MEM, target_id, 0, +- (address >> 2) & 0x3FFFFFFF, data, data_endian); +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_T_WRITE_MEM) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_WRITE_MEM, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- } +- +- return ERROR_OK; +-} +- +-static int aice_fastread_mem(uint8_t target_id, uint8_t *word, uint32_t num_of_words) +-{ +- int retry_times = 0; +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- do { +- aice_pack_htdmb(AICE_CMD_T_FASTREAD_MEM, target_id, num_of_words - 1, 0); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); +- +- LOG_DEBUG("FASTREAD_MEM, COREID: %" PRIu8 ", # of DATA %08" PRIx32, +- target_id, num_of_words); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA + (num_of_words - 1) * 4); +- if (result < 0) { +- LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%d)", +- AICE_FORMAT_DTHMA + (num_of_words - 1) * 4, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthma_multiple_data(&cmd_ack_code, &res_target_id, +- &extra_length, word, data_endian); +- +- if (cmd_ack_code == AICE_CMD_T_FASTREAD_MEM) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_FASTREAD_MEM, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_fastwrite_mem(uint8_t target_id, const uint8_t *word, uint32_t num_of_words) +-{ +- int retry_times = 0; +- +- if (aice_command_mode == AICE_COMMAND_MODE_PACK) { +- aice_usb_packet_flush(); +- } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { +- aice_pack_htdmd_multiple_data(AICE_CMD_T_FASTWRITE_MEM, target_id, +- num_of_words - 1, 0, word, data_endian); +- return aice_usb_packet_append(usb_out_buffer, +- AICE_FORMAT_HTDMD + (num_of_words - 1) * 4, +- AICE_FORMAT_DTHMB); +- } +- +- do { +- aice_pack_htdmd_multiple_data(AICE_CMD_T_FASTWRITE_MEM, target_id, +- num_of_words - 1, 0, word, data_endian); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD + (num_of_words - 1) * 4); +- +- LOG_DEBUG("FASTWRITE_MEM, COREID: %" PRIu8 ", # of DATA %08" PRIx32, +- target_id, num_of_words); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_T_FASTWRITE_MEM) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_FASTWRITE_MEM, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_read_mem_b(uint8_t target_id, uint32_t address, uint32_t *data) +-{ +- int retry_times = 0; +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- do { +- aice_pack_htdmb(AICE_CMD_T_READ_MEM_B, target_id, 0, address); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); +- +- LOG_DEBUG("READ_MEM_B, COREID: %" PRIu8 "", target_id); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); +- if (result != AICE_FORMAT_DTHMA) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMA, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, +- data, data_endian); +- +- if (cmd_ack_code == AICE_CMD_T_READ_MEM_B) { +- LOG_DEBUG("READ_MEM_B response, data: 0x%02" PRIx32, *data); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_READ_MEM_B, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_read_mem_h(uint8_t target_id, uint32_t address, uint32_t *data) +-{ +- int retry_times = 0; +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- do { +- aice_pack_htdmb(AICE_CMD_T_READ_MEM_H, target_id, 0, (address >> 1) & 0x7FFFFFFF); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); +- +- LOG_DEBUG("READ_MEM_H, CORE_ID: %" PRIu8 "", target_id); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); +- if (result != AICE_FORMAT_DTHMA) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMA, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, +- data, data_endian); +- +- if (cmd_ack_code == AICE_CMD_T_READ_MEM_H) { +- LOG_DEBUG("READ_MEM_H response, data: 0x%" PRIx32, *data); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_READ_MEM_H, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_read_mem(uint8_t target_id, uint32_t address, uint32_t *data) +-{ +- int retry_times = 0; +- +- if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || +- (aice_command_mode == AICE_COMMAND_MODE_BATCH)) +- aice_usb_packet_flush(); +- +- do { +- aice_pack_htdmb(AICE_CMD_T_READ_MEM, target_id, 0, +- (address >> 2) & 0x3FFFFFFF); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); +- +- LOG_DEBUG("READ_MEM, COREID: %" PRIu8 "", target_id); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); +- if (result != AICE_FORMAT_DTHMA) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMA, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, +- data, data_endian); +- +- if (cmd_ack_code == AICE_CMD_T_READ_MEM) { +- LOG_DEBUG("READ_MEM response, data: 0x%" PRIx32, *data); +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_T_READ_MEM, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-static int aice_batch_buffer_read(uint8_t buf_index, uint32_t *word, uint32_t num_of_words) +-{ +- int retry_times = 0; +- +- do { +- aice_pack_htdma(AICE_CMD_BATCH_BUFFER_READ, 0, num_of_words - 1, buf_index); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); +- +- LOG_DEBUG("BATCH_BUFFER_READ, # of DATA %08" PRIx32, num_of_words); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA + (num_of_words - 1) * 4); +- if (result < 0) { +- LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%d)", +- AICE_FORMAT_DTHMA + (num_of_words - 1) * 4, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthma_multiple_data(&cmd_ack_code, &res_target_id, +- &extra_length, (uint8_t *)word, data_endian); +- +- if (cmd_ack_code == AICE_CMD_BATCH_BUFFER_READ) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_BATCH_BUFFER_READ, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-int aice_batch_buffer_write(uint8_t buf_index, const uint8_t *word, uint32_t num_of_words) +-{ +- int retry_times = 0; +- +- if (num_of_words == 0) +- return ERROR_OK; +- +- do { +- /* only pack AICE_CMD_BATCH_BUFFER_WRITE command header */ +- aice_pack_htdmc(AICE_CMD_BATCH_BUFFER_WRITE, 0, num_of_words - 1, buf_index, +- 0, data_endian); +- +- /* use append instead of pack */ +- memcpy(usb_out_buffer + 4, word, num_of_words * 4); +- +- aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC + (num_of_words - 1) * 4); +- +- LOG_DEBUG("BATCH_BUFFER_WRITE, # of DATA %08" PRIx32, num_of_words); +- +- int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); +- if (result != AICE_FORMAT_DTHMB) { +- LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", +- AICE_FORMAT_DTHMB, result); +- return ERROR_FAIL; +- } +- +- uint8_t cmd_ack_code; +- uint8_t extra_length; +- uint8_t res_target_id; +- aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); +- +- if (cmd_ack_code == AICE_CMD_BATCH_BUFFER_WRITE) { +- break; +- } else { +- if (retry_times > aice_max_retry_times) { +- LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", +- AICE_CMD_BATCH_BUFFER_WRITE, cmd_ack_code); +- +- return ERROR_FAIL; +- } +- +- /* clear timeout and retry */ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- retry_times++; +- } +- } while (1); +- +- return ERROR_OK; +-} +- +-/***************************************************************************/ +-/* End of AICE commands */ +- +-typedef int (*read_mem_func_t)(uint32_t coreid, uint32_t address, uint32_t *data); +-typedef int (*write_mem_func_t)(uint32_t coreid, uint32_t address, uint32_t data); +- +-static struct aice_nds32_info core_info[AICE_MAX_NUM_CORE]; +-static uint8_t total_num_of_core; +- +-static char *custom_srst_script; +-static char *custom_trst_script; +-static char *custom_restart_script; +-static uint32_t aice_count_to_check_dbger = 30; +- +-static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val); +-static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val); +- +-static int check_suppressed_exception(uint32_t coreid, uint32_t dbger_value) +-{ +- uint32_t ir4_value = 0; +- uint32_t ir6_value = 0; +- /* the default value of handling_suppressed_exception is false */ +- static bool handling_suppressed_exception; +- +- if (handling_suppressed_exception) +- return ERROR_OK; +- +- if ((dbger_value & NDS_DBGER_ALL_SUPRS_EX) == NDS_DBGER_ALL_SUPRS_EX) { +- LOG_ERROR("<-- TARGET WARNING! Exception is detected and suppressed. -->"); +- handling_suppressed_exception = true; +- +- aice_read_reg(coreid, IR4, &ir4_value); +- /* Clear IR6.SUPRS_EXC, IR6.IMP_EXC */ +- aice_read_reg(coreid, IR6, &ir6_value); +- /* +- * For MCU version(MSC_CFG.MCU == 1) like V3m +- * | SWID[30:16] | Reserved[15:10] | SUPRS_EXC[9] | IMP_EXC[8] +- * |VECTOR[7:5] | INST[4] | Exc Type[3:0] | +- * +- * For non-MCU version(MSC_CFG.MCU == 0) like V3 +- * | SWID[30:16] | Reserved[15:14] | SUPRS_EXC[13] | IMP_EXC[12] +- * | VECTOR[11:5] | INST[4] | Exc Type[3:0] | +- */ +- LOG_INFO("EVA: 0x%08" PRIx32, ir4_value); +- LOG_INFO("ITYPE: 0x%08" PRIx32, ir6_value); +- +- ir6_value = ir6_value & (~0x300); /* for MCU */ +- ir6_value = ir6_value & (~0x3000); /* for non-MCU */ +- aice_write_reg(coreid, IR6, ir6_value); +- +- handling_suppressed_exception = false; +- } +- +- return ERROR_OK; +-} +- +-static int check_privilege(uint32_t coreid, uint32_t dbger_value) +-{ +- if ((dbger_value & NDS_DBGER_ILL_SEC_ACC) == NDS_DBGER_ILL_SEC_ACC) { +- LOG_ERROR("<-- TARGET ERROR! Insufficient security privilege " +- "to execute the debug operations. -->"); +- +- /* Clear DBGER.ILL_SEC_ACC */ +- if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, +- NDS_DBGER_ILL_SEC_ACC) != ERROR_OK) +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_check_dbger(uint32_t coreid, uint32_t expect_status) +-{ +- uint32_t i = 0; +- uint32_t value_dbger = 0; +- +- while (1) { +- aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &value_dbger); +- +- if ((value_dbger & expect_status) == expect_status) { +- if (check_suppressed_exception(coreid, value_dbger) != ERROR_OK) +- return ERROR_FAIL; +- if (check_privilege(coreid, value_dbger) != ERROR_OK) +- return ERROR_FAIL; +- return ERROR_OK; +- } +- +- if ((i % 30) == 0) +- keep_alive(); +- +- int64_t then = 0; +- if (i == aice_count_to_check_dbger) +- then = timeval_ms(); +- if (i >= aice_count_to_check_dbger) { +- if ((timeval_ms() - then) > 1000) { +- LOG_ERROR("Timeout (1000ms) waiting for $DBGER status " +- "being 0x%08" PRIx32, expect_status); +- return ERROR_FAIL; +- } +- } +- i++; +- } +- +- return ERROR_FAIL; +-} +- +-static int aice_execute_dim(uint32_t coreid, uint32_t *insts, uint8_t n_inst) +-{ +- /** fill DIM */ +- if (aice_write_dim(coreid, insts, n_inst) != ERROR_OK) +- return ERROR_FAIL; +- +- /** clear DBGER.DPED */ +- if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_DPED) != ERROR_OK) +- return ERROR_FAIL; +- +- /** execute DIM */ +- if (aice_do_execute(coreid) != ERROR_OK) +- return ERROR_FAIL; +- +- /** read DBGER.DPED */ +- if (aice_check_dbger(coreid, NDS_DBGER_DPED) != ERROR_OK) { +- LOG_ERROR("<-- TARGET ERROR! Debug operations do not finish properly: " +- "0x%08" PRIx32 "0x%08" PRIx32 "0x%08" PRIx32 "0x%08" PRIx32 ". -->", +- insts[0], +- insts[1], +- insts[2], +- insts[3]); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) +-{ +- LOG_DEBUG("aice_read_reg, reg_no: 0x%08" PRIx32, num); +- +- uint32_t instructions[4]; /** execute instructions in DIM */ +- +- if (nds32_reg_type(num) == NDS32_REG_TYPE_GPR) { /* general registers */ +- instructions[0] = MTSR_DTR(num); +- instructions[1] = DSB; +- instructions[2] = NOP; +- instructions[3] = BEQ_MINUS_12; +- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_SPR) { /* user special registers */ +- instructions[0] = MFUSR_G0(0, nds32_reg_sr_index(num)); +- instructions[1] = MTSR_DTR(0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_AUMR) { /* audio registers */ +- if ((num >= CB_CTL) && (num <= CBE3)) { +- instructions[0] = AMFAR2(0, nds32_reg_sr_index(num)); +- instructions[1] = MTSR_DTR(0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else { +- instructions[0] = AMFAR(0, nds32_reg_sr_index(num)); +- instructions[1] = MTSR_DTR(0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } +- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_FPU) { /* fpu registers */ +- if (num == FPCSR) { +- instructions[0] = FMFCSR; +- instructions[1] = MTSR_DTR(0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else if (num == FPCFG) { +- instructions[0] = FMFCFG; +- instructions[1] = MTSR_DTR(0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else { +- if (num >= FS0 && num <= FS31) { /* single precision */ +- instructions[0] = FMFSR(0, nds32_reg_sr_index(num)); +- instructions[1] = MTSR_DTR(0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else if (num >= FD0 && num <= FD31) { /* double precision */ +- instructions[0] = FMFDR(0, nds32_reg_sr_index(num)); +- instructions[1] = MTSR_DTR(0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } +- } +- } else { /* system registers */ +- instructions[0] = MFSR(0, nds32_reg_sr_index(num)); +- instructions[1] = MTSR_DTR(0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } +- +- aice_execute_dim(coreid, instructions, 4); +- +- uint32_t value_edmsw = 0; +- aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); +- if (value_edmsw & NDS_EDMSW_WDV) +- aice_read_dtr(coreid, val); +- else { +- LOG_ERROR("<-- TARGET ERROR! The debug target failed to update " +- "the DTR register. -->"); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) +-{ +- LOG_DEBUG("aice_usb_read_reg"); +- +- if (num == R0) { +- *val = core_info[coreid].r0_backup; +- } else if (num == R1) { +- *val = core_info[coreid].r1_backup; +- } else if (num == DR41) { +- /* As target is halted, OpenOCD will backup DR41/DR42/DR43. +- * As user wants to read these registers, OpenOCD should return +- * the backup values, instead of reading the real values. +- * As user wants to write these registers, OpenOCD should write +- * to the backup values, instead of writing to real registers. */ +- *val = core_info[coreid].edmsw_backup; +- } else if (num == DR42) { +- *val = core_info[coreid].edm_ctl_backup; +- } else if ((core_info[coreid].target_dtr_valid == true) && (num == DR43)) { +- *val = core_info[coreid].target_dtr_backup; +- } else { +- if (aice_read_reg(coreid, num, val) != ERROR_OK) +- *val = 0xBBADBEEF; +- } +- +- return ERROR_OK; +-} +- +-static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val) +-{ +- LOG_DEBUG("aice_write_reg, reg_no: 0x%08" PRIx32 ", value: 0x%08" PRIx32, num, val); +- +- uint32_t instructions[4]; /** execute instructions in DIM */ +- uint32_t value_edmsw = 0; +- +- aice_write_dtr(coreid, val); +- aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); +- if (0 == (value_edmsw & NDS_EDMSW_RDV)) { +- LOG_ERROR("<-- TARGET ERROR! AICE failed to write to the DTR register. -->"); +- return ERROR_FAIL; +- } +- +- if (nds32_reg_type(num) == NDS32_REG_TYPE_GPR) { /* general registers */ +- instructions[0] = MFSR_DTR(num); +- instructions[1] = DSB; +- instructions[2] = NOP; +- instructions[3] = BEQ_MINUS_12; +- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_SPR) { /* user special registers */ +- instructions[0] = MFSR_DTR(0); +- instructions[1] = MTUSR_G0(0, nds32_reg_sr_index(num)); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_AUMR) { /* audio registers */ +- if ((num >= CB_CTL) && (num <= CBE3)) { +- instructions[0] = MFSR_DTR(0); +- instructions[1] = AMTAR2(0, nds32_reg_sr_index(num)); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else { +- instructions[0] = MFSR_DTR(0); +- instructions[1] = AMTAR(0, nds32_reg_sr_index(num)); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } +- } else if (nds32_reg_type(num) == NDS32_REG_TYPE_FPU) { /* fpu registers */ +- if (num == FPCSR) { +- instructions[0] = MFSR_DTR(0); +- instructions[1] = FMTCSR; +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else if (num == FPCFG) { +- /* FPCFG is readonly */ +- } else { +- if (num >= FS0 && num <= FS31) { /* single precision */ +- instructions[0] = MFSR_DTR(0); +- instructions[1] = FMTSR(0, nds32_reg_sr_index(num)); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } else if (num >= FD0 && num <= FD31) { /* double precision */ +- instructions[0] = MFSR_DTR(0); +- instructions[1] = FMTDR(0, nds32_reg_sr_index(num)); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } +- } +- } else { +- instructions[0] = MFSR_DTR(0); +- instructions[1] = MTSR(0, nds32_reg_sr_index(num)); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- } +- +- return aice_execute_dim(coreid, instructions, 4); +-} +- +-static int aice_usb_write_reg(uint32_t coreid, uint32_t num, uint32_t val) +-{ +- LOG_DEBUG("aice_usb_write_reg"); +- +- if (num == R0) +- core_info[coreid].r0_backup = val; +- else if (num == R1) +- core_info[coreid].r1_backup = val; +- else if (num == DR42) +- /* As target is halted, OpenOCD will backup DR41/DR42/DR43. +- * As user wants to read these registers, OpenOCD should return +- * the backup values, instead of reading the real values. +- * As user wants to write these registers, OpenOCD should write +- * to the backup values, instead of writing to real registers. */ +- core_info[coreid].edm_ctl_backup = val; +- else if ((core_info[coreid].target_dtr_valid == true) && (num == DR43)) +- core_info[coreid].target_dtr_backup = val; +- else +- return aice_write_reg(coreid, num, val); +- +- return ERROR_OK; +-} +- +-static int aice_usb_open(struct aice_port_param_s *param) +-{ +- const uint16_t vids[] = { param->vid, 0 }; +- const uint16_t pids[] = { param->pid, 0 }; +- struct libusb_device_handle *devh; +- +- if (jtag_libusb_open(vids, pids, &devh, NULL) != ERROR_OK) +- return ERROR_FAIL; +- +- /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS +- * AREA!!!!!!!!!!! The behavior of libusb is not completely +- * consistent across Windows, Linux, and Mac OS X platforms. +- * The actions taken in the following compiler conditionals may +- * not agree with published documentation for libusb, but were +- * found to be necessary through trials and tribulations. Even +- * little tweaks can break one or more platforms, so if you do +- * make changes test them carefully on all platforms before +- * committing them! +- */ +- +-#if IS_WIN32 == 0 +- +- libusb_reset_device(devh); +- +-#if IS_DARWIN == 0 +- +- int timeout = 5; +- /* reopen jlink after usb_reset +- * on win32 this may take a second or two to re-enumerate */ +- int retval; +- while ((retval = jtag_libusb_open(vids, pids, &devh, NULL)) != ERROR_OK) { +- usleep(1000); +- timeout--; +- if (!timeout) +- break; +- } +- if (retval != ERROR_OK) +- return ERROR_FAIL; +-#endif +- +-#endif +- +- /* usb_set_configuration required under win32 */ +- libusb_set_configuration(devh, 0); +- libusb_claim_interface(devh, 0); +- +- unsigned int aice_read_ep; +- unsigned int aice_write_ep; +- +- jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1, LIBUSB_TRANSFER_TYPE_BULK); +- LOG_DEBUG("aice_read_ep=0x%x, aice_write_ep=0x%x", aice_read_ep, aice_write_ep); +- +- aice_handler.usb_read_ep = aice_read_ep; +- aice_handler.usb_write_ep = aice_write_ep; +- aice_handler.usb_handle = devh; +- +- return ERROR_OK; +-} +- +-static int aice_usb_read_reg_64(uint32_t coreid, uint32_t num, uint64_t *val) +-{ +- LOG_DEBUG("aice_usb_read_reg_64, %s", nds32_reg_simple_name(num)); +- +- uint32_t value; +- uint32_t high_value; +- +- if (aice_read_reg(coreid, num, &value) != ERROR_OK) +- value = 0xBBADBEEF; +- +- aice_read_reg(coreid, R1, &high_value); +- +- LOG_DEBUG("low: 0x%08" PRIx32 ", high: 0x%08" PRIx32 "\n", value, high_value); +- +- if (data_endian == AICE_BIG_ENDIAN) +- *val = (((uint64_t)high_value) << 32) | value; +- else +- *val = (((uint64_t)value) << 32) | high_value; +- +- return ERROR_OK; +-} +- +-static int aice_usb_write_reg_64(uint32_t coreid, uint32_t num, uint64_t val) +-{ +- uint32_t value; +- uint32_t high_value; +- +- if (data_endian == AICE_BIG_ENDIAN) { +- value = val & 0xFFFFFFFF; +- high_value = (val >> 32) & 0xFFFFFFFF; +- } else { +- high_value = val & 0xFFFFFFFF; +- value = (val >> 32) & 0xFFFFFFFF; +- } +- +- LOG_DEBUG("aice_usb_write_reg_64, %s, low: 0x%08" PRIx32 ", high: 0x%08" PRIx32 "\n", +- nds32_reg_simple_name(num), value, high_value); +- +- aice_write_reg(coreid, R1, high_value); +- return aice_write_reg(coreid, num, value); +-} +- +-static int aice_get_version_info(void) +-{ +- uint32_t hardware_version; +- uint32_t firmware_version; +- uint32_t fpga_version; +- +- if (aice_read_ctrl(AICE_READ_CTRL_GET_HARDWARE_VERSION, &hardware_version) != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_read_ctrl(AICE_READ_CTRL_GET_FIRMWARE_VERSION, &firmware_version) != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_read_ctrl(AICE_READ_CTRL_GET_FPGA_VERSION, &fpga_version) != ERROR_OK) +- return ERROR_FAIL; +- +- LOG_INFO("AICE version: hw_ver = 0x%" PRIx32 ", fw_ver = 0x%" PRIx32 ", fpga_ver = 0x%" PRIx32, +- hardware_version, firmware_version, fpga_version); +- +- return ERROR_OK; +-} +- +-#define LINE_BUFFER_SIZE 1024 +- +-static int aice_execute_custom_script(const char *script) +-{ +- FILE *script_fd; +- char line_buffer[LINE_BUFFER_SIZE]; +- char *op_str; +- char *reset_str; +- uint32_t delay; +- uint32_t write_ctrl_value; +- bool set_op; +- +- script_fd = fopen(script, "r"); +- if (!script_fd) { +- return ERROR_FAIL; +- } else { +- while (fgets(line_buffer, LINE_BUFFER_SIZE, script_fd)) { +- /* execute operations */ +- set_op = false; +- op_str = strstr(line_buffer, "set"); +- if (op_str) { +- set_op = true; +- goto get_reset_type; +- } +- +- op_str = strstr(line_buffer, "clear"); +- if (!op_str) +- continue; +-get_reset_type: +- reset_str = strstr(op_str, "srst"); +- if (reset_str) { +- if (set_op) +- write_ctrl_value = AICE_CUSTOM_DELAY_SET_SRST; +- else +- write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_SRST; +- goto get_delay; +- } +- reset_str = strstr(op_str, "dbgi"); +- if (reset_str) { +- if (set_op) +- write_ctrl_value = AICE_CUSTOM_DELAY_SET_DBGI; +- else +- write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_DBGI; +- goto get_delay; +- } +- reset_str = strstr(op_str, "trst"); +- if (reset_str) { +- if (set_op) +- write_ctrl_value = AICE_CUSTOM_DELAY_SET_TRST; +- else +- write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_TRST; +- goto get_delay; +- } +- continue; +-get_delay: +- /* get delay */ +- delay = strtoul(reset_str + 4, NULL, 0); +- write_ctrl_value |= (delay << 16); +- +- if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, +- write_ctrl_value) != ERROR_OK) { +- fclose(script_fd); +- return ERROR_FAIL; +- } +- } +- fclose(script_fd); +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_clock(int set_clock) +-{ +- if (set_clock & AICE_TCK_CONTROL_TCK_SCAN) { +- if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL, +- AICE_TCK_CONTROL_TCK_SCAN) != ERROR_OK) +- return ERROR_FAIL; +- +- /* Read out TCK_SCAN clock value */ +- uint32_t scan_clock; +- if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &scan_clock) != ERROR_OK) +- return ERROR_FAIL; +- +- scan_clock &= 0x0F; +- +- uint32_t scan_base_freq; +- if (scan_clock & 0x8) +- scan_base_freq = 48000; /* 48 MHz */ +- else +- scan_base_freq = 30000; /* 30 MHz */ +- +- uint32_t set_base_freq; +- if (set_clock & 0x8) +- set_base_freq = 48000; +- else +- set_base_freq = 30000; +- +- uint32_t set_freq; +- uint32_t scan_freq; +- set_freq = set_base_freq >> (set_clock & 0x7); +- scan_freq = scan_base_freq >> (scan_clock & 0x7); +- +- if (scan_freq < set_freq) { +- LOG_ERROR("User specifies higher jtag clock than TCK_SCAN clock"); +- return ERROR_FAIL; +- } +- } +- +- if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL, set_clock) != ERROR_OK) +- return ERROR_FAIL; +- +- uint32_t check_speed; +- if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &check_speed) != ERROR_OK) +- return ERROR_FAIL; +- +- if (((int)check_speed & 0x0F) != set_clock) { +- LOG_ERROR("Set jtag clock failed"); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_edm_init(uint32_t coreid) +-{ +- aice_write_edmsr(coreid, NDS_EDM_SR_DIMBR, 0xFFFF0000); +- aice_write_misc(coreid, NDS_EDM_MISC_DIMIR, 0); +- +- /* unconditionally try to turn on V3_EDM_MODE */ +- uint32_t edm_ctl_value; +- aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value); +- aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value | 0x00000040); +- +- /* clear DBGER */ +- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, +- NDS_DBGER_DPED | NDS_DBGER_CRST | NDS_DBGER_AT_MAX); +- +- /* get EDM version */ +- uint32_t value_edmcfg; +- aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CFG, &value_edmcfg); +- core_info[coreid].edm_version = (value_edmcfg >> 16) & 0xFFFF; +- +- return ERROR_OK; +-} +- +-static bool is_v2_edm(uint32_t coreid) +-{ +- if ((core_info[coreid].edm_version & 0x1000) == 0) +- return true; +- else +- return false; +-} +- +-static int aice_init_edm_registers(uint32_t coreid, bool clear_dex_use_psw) +-{ +- /* enable DEH_SEL & MAX_STOP & V3_EDM_MODE & DBGI_MASK */ +- uint32_t host_edm_ctl = core_info[coreid].edm_ctl_backup | 0xA000004F; +- if (clear_dex_use_psw) +- /* After entering debug mode, OpenOCD may set +- * DEX_USE_PSW accidentally through backup value +- * of target EDM_CTL. +- * So, clear DEX_USE_PSW by force. */ +- host_edm_ctl &= ~(0x40000000); +- +- LOG_DEBUG("aice_init_edm_registers - EDM_CTL: 0x%08" PRIx32, host_edm_ctl); +- +- int result = aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, host_edm_ctl); +- +- return result; +-} +- +-/** +- * EDM_CTL will be modified by OpenOCD as debugging. OpenOCD has the +- * responsibility to keep EDM_CTL untouched after debugging. +- * +- * There are two scenarios to consider: +- * 1. single step/running as debugging (running under debug session) +- * 2. detached from gdb (exit debug session) +- * +- * So, we need to bakcup EDM_CTL before halted and restore it after +- * running. The difference of these two scenarios is EDM_CTL.DEH_SEL +- * is on for scenario 1, and off for scenario 2. +- */ +-static int aice_backup_edm_registers(uint32_t coreid) +-{ +- int result = aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, +- &core_info[coreid].edm_ctl_backup); +- +- /* To call aice_backup_edm_registers() after DEX on, DEX_USE_PSW +- * may be not correct. (For example, hit breakpoint, then backup +- * EDM_CTL. EDM_CTL.DEX_USE_PSW will be cleared.) Because debug +- * interrupt will clear DEX_USE_PSW, DEX_USE_PSW is always off after +- * DEX is on. It only backups correct value before OpenOCD issues DBGI. +- * (Backup EDM_CTL, then issue DBGI actively (refer aice_usb_halt())) */ +- if (core_info[coreid].edm_ctl_backup & 0x40000000) +- core_info[coreid].dex_use_psw_on = true; +- else +- core_info[coreid].dex_use_psw_on = false; +- +- LOG_DEBUG("aice_backup_edm_registers - EDM_CTL: 0x%08" PRIx32 ", DEX_USE_PSW: %s", +- core_info[coreid].edm_ctl_backup, +- core_info[coreid].dex_use_psw_on ? "on" : "off"); +- +- return result; +-} +- +-static int aice_restore_edm_registers(uint32_t coreid) +-{ +- LOG_DEBUG("aice_restore_edm_registers -"); +- +- /* set DEH_SEL, because target still under EDM control */ +- int result = aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, +- core_info[coreid].edm_ctl_backup | 0x80000000); +- +- return result; +-} +- +-static int aice_backup_tmp_registers(uint32_t coreid) +-{ +- LOG_DEBUG("backup_tmp_registers -"); +- +- /* backup target DTR first(if the target DTR is valid) */ +- uint32_t value_edmsw = 0; +- aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); +- core_info[coreid].edmsw_backup = value_edmsw; +- if (value_edmsw & 0x1) { /* EDMSW.WDV == 1 */ +- aice_read_dtr(coreid, &core_info[coreid].target_dtr_backup); +- core_info[coreid].target_dtr_valid = true; +- +- LOG_DEBUG("Backup target DTR: 0x%08" PRIx32, core_info[coreid].target_dtr_backup); +- } else { +- core_info[coreid].target_dtr_valid = false; +- } +- +- /* Target DTR has been backup, then backup $R0 and $R1 */ +- aice_read_reg(coreid, R0, &core_info[coreid].r0_backup); +- aice_read_reg(coreid, R1, &core_info[coreid].r1_backup); +- +- /* backup host DTR(if the host DTR is valid) */ +- if (value_edmsw & 0x2) { /* EDMSW.RDV == 1*/ +- /* read out host DTR and write into target DTR, then use aice_read_edmsr to +- * read out */ +- uint32_t instructions[4] = { +- MFSR_DTR(R0), /* R0 has already been backup */ +- DSB, +- MTSR_DTR(R0), +- BEQ_MINUS_12 +- }; +- aice_execute_dim(coreid, instructions, 4); +- +- aice_read_dtr(coreid, &core_info[coreid].host_dtr_backup); +- core_info[coreid].host_dtr_valid = true; +- +- LOG_DEBUG("Backup host DTR: 0x%08" PRIx32, core_info[coreid].host_dtr_backup); +- } else { +- core_info[coreid].host_dtr_valid = false; +- } +- +- LOG_DEBUG("r0: 0x%08" PRIx32 ", r1: 0x%08" PRIx32, +- core_info[coreid].r0_backup, core_info[coreid].r1_backup); +- +- return ERROR_OK; +-} +- +-static int aice_restore_tmp_registers(uint32_t coreid) +-{ +- LOG_DEBUG("restore_tmp_registers - r0: 0x%08" PRIx32 ", r1: 0x%08" PRIx32, +- core_info[coreid].r0_backup, core_info[coreid].r1_backup); +- +- if (core_info[coreid].target_dtr_valid) { +- uint32_t instructions[4] = { +- SETHI(R0, core_info[coreid].target_dtr_backup >> 12), +- ORI(R0, R0, core_info[coreid].target_dtr_backup & 0x00000FFF), +- NOP, +- BEQ_MINUS_12 +- }; +- aice_execute_dim(coreid, instructions, 4); +- +- instructions[0] = MTSR_DTR(R0); +- instructions[1] = DSB; +- instructions[2] = NOP; +- instructions[3] = BEQ_MINUS_12; +- aice_execute_dim(coreid, instructions, 4); +- +- LOG_DEBUG("Restore target DTR: 0x%08" PRIx32, core_info[coreid].target_dtr_backup); +- } +- +- aice_write_reg(coreid, R0, core_info[coreid].r0_backup); +- aice_write_reg(coreid, R1, core_info[coreid].r1_backup); +- +- if (core_info[coreid].host_dtr_valid) { +- aice_write_dtr(coreid, core_info[coreid].host_dtr_backup); +- +- LOG_DEBUG("Restore host DTR: 0x%08" PRIx32, core_info[coreid].host_dtr_backup); +- } +- +- return ERROR_OK; +-} +- +-static int aice_open_device(struct aice_port_param_s *param) +-{ +- if (aice_usb_open(param) != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_get_version_info() == ERROR_FAIL) { +- LOG_ERROR("Cannot get AICE version!"); +- return ERROR_FAIL; +- } +- +- LOG_INFO("AICE initialization started"); +- +- /* attempt to reset Andes EDM */ +- if (aice_reset_box() == ERROR_FAIL) { +- LOG_ERROR("Cannot initial AICE box!"); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_jtag_clock(uint32_t a_clock) +-{ +- jtag_clock = a_clock; +- +- if (aice_usb_set_clock(a_clock) != ERROR_OK) { +- LOG_ERROR("Cannot set AICE JTAG clock!"); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_close(void) +-{ +- jtag_libusb_close(aice_handler.usb_handle); +- +- free(custom_srst_script); +- free(custom_trst_script); +- free(custom_restart_script); +- return ERROR_OK; +-} +- +-static int aice_core_init(uint32_t coreid) +-{ +- core_info[coreid].access_channel = NDS_MEMORY_ACC_CPU; +- core_info[coreid].memory_select = NDS_MEMORY_SELECT_AUTO; +- core_info[coreid].core_state = AICE_TARGET_UNKNOWN; +- +- return ERROR_OK; +-} +- +-static int aice_usb_idcode(uint32_t *idcode, uint8_t *num_of_idcode) +-{ +- int retval; +- +- retval = aice_scan_chain(idcode, num_of_idcode); +- if (retval == ERROR_OK) { +- for (int i = 0; i < *num_of_idcode; i++) { +- aice_core_init(i); +- aice_edm_init(i); +- } +- total_num_of_core = *num_of_idcode; +- } +- +- return retval; +-} +- +-static int aice_usb_halt(uint32_t coreid) +-{ +- if (core_info[coreid].core_state == AICE_TARGET_HALTED) { +- LOG_DEBUG("aice_usb_halt check halted"); +- return ERROR_OK; +- } +- +- LOG_DEBUG("aice_usb_halt"); +- +- /** backup EDM registers */ +- aice_backup_edm_registers(coreid); +- /** init EDM for host debugging */ +- /** no need to clear dex_use_psw, because dbgi will clear it */ +- aice_init_edm_registers(coreid, false); +- +- /** Clear EDM_CTL.DBGIM & EDM_CTL.DBGACKM */ +- uint32_t edm_ctl_value = 0; +- aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value); +- if (edm_ctl_value & 0x3) +- aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value & ~(0x3)); +- +- uint32_t dbger = 0; +- uint32_t acc_ctl_value = 0; +- +- core_info[coreid].debug_under_dex_on = false; +- aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger); +- +- if (dbger & NDS_DBGER_AT_MAX) +- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level. -->"); +- +- if (dbger & NDS_DBGER_DEX) { +- if (is_v2_edm(coreid) == false) { +- /** debug 'debug mode'. use force_debug to issue dbgi */ +- aice_read_misc(coreid, NDS_EDM_MISC_ACC_CTL, &acc_ctl_value); +- acc_ctl_value |= 0x8; +- aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, acc_ctl_value); +- core_info[coreid].debug_under_dex_on = true; +- +- aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0); +- /* If CPU stalled due to AT_MAX, clear AT_MAX status. */ +- if (dbger & NDS_DBGER_AT_MAX) +- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_AT_MAX); +- } +- } else { +- /** Issue DBGI normally */ +- aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0); +- /* If CPU stalled due to AT_MAX, clear AT_MAX status. */ +- if (dbger & NDS_DBGER_AT_MAX) +- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_AT_MAX); +- } +- +- if (aice_check_dbger(coreid, NDS_DBGER_DEX) != ERROR_OK) { +- LOG_ERROR("<-- TARGET ERROR! Unable to stop the debug target through DBGI. -->"); +- return ERROR_FAIL; +- } +- +- if (core_info[coreid].debug_under_dex_on) { +- if (core_info[coreid].dex_use_psw_on == false) { +- /* under debug 'debug mode', force $psw to 'debug mode' behavior */ +- /* !!!NOTICE!!! this is workaround for debug 'debug mode'. +- * it is only for debugging 'debug exception handler' purpose. +- * after openocd detaches from target, target behavior is +- * undefined. */ +- uint32_t ir0_value = 0; +- uint32_t debug_mode_ir0_value; +- aice_read_reg(coreid, IR0, &ir0_value); +- debug_mode_ir0_value = ir0_value | 0x408; /* turn on DEX, set POM = 1 */ +- debug_mode_ir0_value &= ~(0x000000C1); /* turn off DT/IT/GIE */ +- aice_write_reg(coreid, IR0, debug_mode_ir0_value); +- } +- } +- +- /** set EDM_CTL.DBGIM & EDM_CTL.DBGACKM after halt */ +- if (edm_ctl_value & 0x3) +- aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value); +- +- /* backup r0 & r1 */ +- aice_backup_tmp_registers(coreid); +- core_info[coreid].core_state = AICE_TARGET_HALTED; +- +- return ERROR_OK; +-} +- +-static int aice_usb_state(uint32_t coreid, enum aice_target_state_s *state) +-{ +- uint32_t dbger_value; +- uint32_t ice_state; +- +- int result = aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger_value); +- +- if (result == ERROR_AICE_TIMEOUT) { +- if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &ice_state) != ERROR_OK) { +- LOG_ERROR("<-- AICE ERROR! AICE is unplugged. -->"); +- return ERROR_FAIL; +- } +- +- if ((ice_state & 0x20) == 0) { +- LOG_ERROR("<-- TARGET ERROR! Target is disconnected with AICE. -->"); +- return ERROR_FAIL; +- } else { +- return ERROR_FAIL; +- } +- } else if (result == ERROR_AICE_DISCONNECT) { +- LOG_ERROR("<-- AICE ERROR! AICE is unplugged. -->"); +- return ERROR_FAIL; +- } +- +- if ((dbger_value & NDS_DBGER_ILL_SEC_ACC) == NDS_DBGER_ILL_SEC_ACC) { +- LOG_ERROR("<-- TARGET ERROR! Insufficient security privilege. -->"); +- +- /* Clear ILL_SEC_ACC */ +- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_ILL_SEC_ACC); +- +- *state = AICE_TARGET_RUNNING; +- core_info[coreid].core_state = AICE_TARGET_RUNNING; +- } else if ((dbger_value & NDS_DBGER_AT_MAX) == NDS_DBGER_AT_MAX) { +- /* Issue DBGI to exit cpu stall */ +- aice_usb_halt(coreid); +- +- /* Read OIPC to find out the trigger point */ +- uint32_t ir11_value; +- aice_read_reg(coreid, IR11, &ir11_value); +- +- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level; " +- "CPU is stalled at 0x%08" PRIx32 " for debugging. -->", ir11_value); +- +- *state = AICE_TARGET_HALTED; +- } else if ((dbger_value & NDS_DBGER_CRST) == NDS_DBGER_CRST) { +- LOG_DEBUG("DBGER.CRST is on."); +- +- *state = AICE_TARGET_RESET; +- core_info[coreid].core_state = AICE_TARGET_RUNNING; +- +- /* Clear CRST */ +- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_CRST); +- } else if ((dbger_value & NDS_DBGER_DEX) == NDS_DBGER_DEX) { +- if (core_info[coreid].core_state == AICE_TARGET_RUNNING) { +- /* enter debug mode, init EDM registers */ +- /* backup EDM registers */ +- aice_backup_edm_registers(coreid); +- /* init EDM for host debugging */ +- aice_init_edm_registers(coreid, true); +- aice_backup_tmp_registers(coreid); +- core_info[coreid].core_state = AICE_TARGET_HALTED; +- } else if (core_info[coreid].core_state == AICE_TARGET_UNKNOWN) { +- /* debug 'debug mode', use force debug to halt core */ +- aice_usb_halt(coreid); +- } +- *state = AICE_TARGET_HALTED; +- } else { +- *state = AICE_TARGET_RUNNING; +- core_info[coreid].core_state = AICE_TARGET_RUNNING; +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_reset(void) +-{ +- if (aice_reset_box() != ERROR_OK) +- return ERROR_FAIL; +- +- /* issue TRST */ +- if (!custom_trst_script) { +- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, +- AICE_JTAG_PIN_CONTROL_TRST) != ERROR_OK) +- return ERROR_FAIL; +- } else { +- /* custom trst operations */ +- if (aice_execute_custom_script(custom_trst_script) != ERROR_OK) +- return ERROR_FAIL; +- } +- +- if (aice_usb_set_clock(jtag_clock) != ERROR_OK) +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int aice_issue_srst(uint32_t coreid) +-{ +- LOG_DEBUG("aice_issue_srst"); +- +- /* After issuing srst, target will be running. So we need to restore EDM_CTL. */ +- aice_restore_edm_registers(coreid); +- +- if (!custom_srst_script) { +- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, +- AICE_JTAG_PIN_CONTROL_SRST) != ERROR_OK) +- return ERROR_FAIL; +- } else { +- /* custom srst operations */ +- if (aice_execute_custom_script(custom_srst_script) != ERROR_OK) +- return ERROR_FAIL; +- } +- +- /* wait CRST infinitely */ +- uint32_t dbger_value; +- int i = 0; +- while (1) { +- if (aice_read_misc(coreid, +- NDS_EDM_MISC_DBGER, &dbger_value) != ERROR_OK) +- return ERROR_FAIL; +- +- if (dbger_value & NDS_DBGER_CRST) +- break; +- +- if ((i % 30) == 0) +- keep_alive(); +- i++; +- } +- +- core_info[coreid].host_dtr_valid = false; +- core_info[coreid].target_dtr_valid = false; +- +- core_info[coreid].core_state = AICE_TARGET_RUNNING; +- return ERROR_OK; +-} +- +-static int aice_issue_reset_hold(uint32_t coreid) +-{ +- LOG_DEBUG("aice_issue_reset_hold"); +- +- /* set no_dbgi_pin to 0 */ +- uint32_t pin_status; +- aice_read_ctrl(AICE_READ_CTRL_GET_JTAG_PIN_STATUS, &pin_status); +- if (pin_status & 0x4) +- aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status & (~0x4)); +- +- /* issue restart */ +- if (!custom_restart_script) { +- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, +- AICE_JTAG_PIN_CONTROL_RESTART) != ERROR_OK) +- return ERROR_FAIL; +- } else { +- /* custom restart operations */ +- if (aice_execute_custom_script(custom_restart_script) != ERROR_OK) +- return ERROR_FAIL; +- } +- +- if (aice_check_dbger(coreid, NDS_DBGER_CRST | NDS_DBGER_DEX) == ERROR_OK) { +- aice_backup_tmp_registers(coreid); +- core_info[coreid].core_state = AICE_TARGET_HALTED; +- +- return ERROR_OK; +- } else { +- /* set no_dbgi_pin to 1 */ +- aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status | 0x4); +- +- /* issue restart again */ +- if (!custom_restart_script) { +- if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, +- AICE_JTAG_PIN_CONTROL_RESTART) != ERROR_OK) +- return ERROR_FAIL; +- } else { +- /* custom restart operations */ +- if (aice_execute_custom_script(custom_restart_script) != ERROR_OK) +- return ERROR_FAIL; +- } +- +- if (aice_check_dbger(coreid, NDS_DBGER_CRST | NDS_DBGER_DEX) == ERROR_OK) { +- aice_backup_tmp_registers(coreid); +- core_info[coreid].core_state = AICE_TARGET_HALTED; +- +- return ERROR_OK; +- } +- +- /* do software reset-and-hold */ +- aice_issue_srst(coreid); +- aice_usb_halt(coreid); +- +- uint32_t value_ir3; +- aice_read_reg(coreid, IR3, &value_ir3); +- aice_write_reg(coreid, PC, value_ir3 & 0xFFFF0000); +- } +- +- return ERROR_FAIL; +-} +- +-static int aice_issue_reset_hold_multi(void) +-{ +- uint32_t write_ctrl_value = 0; +- +- /* set SRST */ +- write_ctrl_value = AICE_CUSTOM_DELAY_SET_SRST; +- write_ctrl_value |= (0x200 << 16); +- if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, +- write_ctrl_value) != ERROR_OK) +- return ERROR_FAIL; +- +- for (uint8_t i = 0 ; i < total_num_of_core ; i++) +- aice_write_misc(i, NDS_EDM_MISC_EDM_CMDR, 0); +- +- /* clear SRST */ +- write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_SRST; +- write_ctrl_value |= (0x200 << 16); +- if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, +- write_ctrl_value) != ERROR_OK) +- return ERROR_FAIL; +- +- for (uint8_t i = 0; i < total_num_of_core; i++) +- aice_edm_init(i); +- +- return ERROR_FAIL; +-} +- +-static int aice_usb_assert_srst(uint32_t coreid, enum aice_srst_type_s srst) +-{ +- if ((srst != AICE_SRST) && (srst != AICE_RESET_HOLD)) +- return ERROR_FAIL; +- +- /* clear DBGER */ +- if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, +- NDS_DBGER_CLEAR_ALL) != ERROR_OK) +- return ERROR_FAIL; +- +- int result = ERROR_OK; +- if (srst == AICE_SRST) +- result = aice_issue_srst(coreid); +- else { +- if (total_num_of_core == 1) +- result = aice_issue_reset_hold(coreid); +- else +- result = aice_issue_reset_hold_multi(); +- } +- +- /* Clear DBGER.CRST after reset to avoid 'core-reset checking' errors. +- * assert_srst is user-intentional reset behavior, so we could +- * clear DBGER.CRST safely. +- */ +- if (aice_write_misc(coreid, +- NDS_EDM_MISC_DBGER, NDS_DBGER_CRST) != ERROR_OK) +- return ERROR_FAIL; +- +- return result; +-} +- +-static int aice_usb_run(uint32_t coreid) +-{ +- LOG_DEBUG("aice_usb_run"); +- +- uint32_t dbger_value; +- if (aice_read_misc(coreid, +- NDS_EDM_MISC_DBGER, &dbger_value) != ERROR_OK) +- return ERROR_FAIL; +- +- if ((dbger_value & NDS_DBGER_DEX) != NDS_DBGER_DEX) { +- LOG_WARNING("<-- TARGET WARNING! The debug target exited " +- "the debug mode unexpectedly. -->"); +- return ERROR_FAIL; +- } +- +- /* restore r0 & r1 before free run */ +- aice_restore_tmp_registers(coreid); +- core_info[coreid].core_state = AICE_TARGET_RUNNING; +- +- /* clear DBGER */ +- aice_write_misc(coreid, NDS_EDM_MISC_DBGER, +- NDS_DBGER_CLEAR_ALL); +- +- /** restore EDM registers */ +- /** OpenOCD should restore EDM_CTL **before** to exit debug state. +- * Otherwise, following instruction will read wrong EDM_CTL value. +- * +- * pc -> mfsr $p0, EDM_CTL (single step) +- * slli $p0, $p0, 1 +- * slri $p0, $p0, 31 +- */ +- aice_restore_edm_registers(coreid); +- +- /** execute instructions in DIM */ +- uint32_t instructions[4] = { +- NOP, +- NOP, +- NOP, +- IRET +- }; +- int result = aice_execute_dim(coreid, instructions, 4); +- +- return result; +-} +- +-static int aice_usb_step(uint32_t coreid) +-{ +- LOG_DEBUG("aice_usb_step"); +- +- uint32_t ir0_value; +- uint32_t ir0_reg_num; +- +- if (is_v2_edm(coreid) == true) +- /* V2 EDM will push interrupt stack as debug exception */ +- ir0_reg_num = IR1; +- else +- ir0_reg_num = IR0; +- +- /** enable HSS */ +- aice_read_reg(coreid, ir0_reg_num, &ir0_value); +- if ((ir0_value & 0x800) == 0) { +- /** set PSW.HSS */ +- ir0_value |= (0x01 << 11); +- aice_write_reg(coreid, ir0_reg_num, ir0_value); +- } +- +- if (aice_usb_run(coreid) == ERROR_FAIL) +- return ERROR_FAIL; +- +- int i = 0; +- enum aice_target_state_s state; +- while (1) { +- /* read DBGER */ +- if (aice_usb_state(coreid, &state) != ERROR_OK) +- return ERROR_FAIL; +- +- if (state == AICE_TARGET_HALTED) +- break; +- +- int64_t then = 0; +- if (i == 30) +- then = timeval_ms(); +- +- if (i >= 30) { +- if ((timeval_ms() - then) > 1000) +- LOG_WARNING("Timeout (1000ms) waiting for halt to complete"); +- +- return ERROR_FAIL; +- } +- i++; +- } +- +- /** disable HSS */ +- aice_read_reg(coreid, ir0_reg_num, &ir0_value); +- ir0_value &= ~(0x01 << 11); +- aice_write_reg(coreid, ir0_reg_num, ir0_value); +- +- return ERROR_OK; +-} +- +-static int aice_usb_read_mem_b_bus(uint32_t coreid, uint32_t address, uint32_t *data) +-{ +- return aice_read_mem_b(coreid, address, data); +-} +- +-static int aice_usb_read_mem_h_bus(uint32_t coreid, uint32_t address, uint32_t *data) +-{ +- return aice_read_mem_h(coreid, address, data); +-} +- +-static int aice_usb_read_mem_w_bus(uint32_t coreid, uint32_t address, uint32_t *data) +-{ +- return aice_read_mem(coreid, address, data); +-} +- +-static int aice_usb_read_mem_b_dim(uint32_t coreid, uint32_t address, uint32_t *data) +-{ +- uint32_t value; +- uint32_t instructions[4] = { +- LBI_BI(R1, R0), +- MTSR_DTR(R1), +- DSB, +- BEQ_MINUS_12 +- }; +- +- aice_execute_dim(coreid, instructions, 4); +- +- aice_read_dtr(coreid, &value); +- *data = value & 0xFF; +- +- return ERROR_OK; +-} +- +-static int aice_usb_read_mem_h_dim(uint32_t coreid, uint32_t address, uint32_t *data) +-{ +- uint32_t value; +- uint32_t instructions[4] = { +- LHI_BI(R1, R0), +- MTSR_DTR(R1), +- DSB, +- BEQ_MINUS_12 +- }; +- +- aice_execute_dim(coreid, instructions, 4); +- +- aice_read_dtr(coreid, &value); +- *data = value & 0xFFFF; +- +- return ERROR_OK; +-} +- +-static int aice_usb_read_mem_w_dim(uint32_t coreid, uint32_t address, uint32_t *data) +-{ +- uint32_t instructions[4] = { +- LWI_BI(R1, R0), +- MTSR_DTR(R1), +- DSB, +- BEQ_MINUS_12 +- }; +- +- aice_execute_dim(coreid, instructions, 4); +- +- aice_read_dtr(coreid, data); +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_address_dim(uint32_t coreid, uint32_t address) +-{ +- uint32_t instructions[4] = { +- SETHI(R0, address >> 12), +- ORI(R0, R0, address & 0x00000FFF), +- NOP, +- BEQ_MINUS_12 +- }; +- +- return aice_execute_dim(coreid, instructions, 4); +-} +- +-static int aice_usb_read_memory_unit(uint32_t coreid, uint32_t addr, uint32_t size, +- uint32_t count, uint8_t *buffer) +-{ +- LOG_DEBUG("aice_usb_read_memory_unit, addr: 0x%08" PRIx32 +- ", size: %" PRIu32 ", count: %" PRIu32 "", +- addr, size, count); +- +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) +- aice_usb_set_address_dim(coreid, addr); +- +- uint32_t value; +- size_t i; +- read_mem_func_t read_mem_func; +- +- switch (size) { +- case 1: +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) +- read_mem_func = aice_usb_read_mem_b_bus; +- else +- read_mem_func = aice_usb_read_mem_b_dim; +- +- for (i = 0; i < count; i++) { +- read_mem_func(coreid, addr, &value); +- *buffer++ = (uint8_t)value; +- addr++; +- } +- break; +- case 2: +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) +- read_mem_func = aice_usb_read_mem_h_bus; +- else +- read_mem_func = aice_usb_read_mem_h_dim; +- +- for (i = 0; i < count; i++) { +- read_mem_func(coreid, addr, &value); +- uint16_t svalue = value; +- memcpy(buffer, &svalue, sizeof(uint16_t)); +- buffer += 2; +- addr += 2; +- } +- break; +- case 4: +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) +- read_mem_func = aice_usb_read_mem_w_bus; +- else +- read_mem_func = aice_usb_read_mem_w_dim; +- +- for (i = 0; i < count; i++) { +- read_mem_func(coreid, addr, &value); +- memcpy(buffer, &value, sizeof(uint32_t)); +- buffer += 4; +- addr += 4; +- } +- break; +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_write_mem_b_bus(uint32_t coreid, uint32_t address, uint32_t data) +-{ +- return aice_write_mem_b(coreid, address, data); +-} +- +-static int aice_usb_write_mem_h_bus(uint32_t coreid, uint32_t address, uint32_t data) +-{ +- return aice_write_mem_h(coreid, address, data); +-} +- +-static int aice_usb_write_mem_w_bus(uint32_t coreid, uint32_t address, uint32_t data) +-{ +- return aice_write_mem(coreid, address, data); +-} +- +-static int aice_usb_write_mem_b_dim(uint32_t coreid, uint32_t address, uint32_t data) +-{ +- uint32_t instructions[4] = { +- MFSR_DTR(R1), +- SBI_BI(R1, R0), +- DSB, +- BEQ_MINUS_12 +- }; +- +- aice_write_dtr(coreid, data & 0xFF); +- aice_execute_dim(coreid, instructions, 4); +- +- return ERROR_OK; +-} +- +-static int aice_usb_write_mem_h_dim(uint32_t coreid, uint32_t address, uint32_t data) +-{ +- uint32_t instructions[4] = { +- MFSR_DTR(R1), +- SHI_BI(R1, R0), +- DSB, +- BEQ_MINUS_12 +- }; +- +- aice_write_dtr(coreid, data & 0xFFFF); +- aice_execute_dim(coreid, instructions, 4); +- +- return ERROR_OK; +-} +- +-static int aice_usb_write_mem_w_dim(uint32_t coreid, uint32_t address, uint32_t data) +-{ +- uint32_t instructions[4] = { +- MFSR_DTR(R1), +- SWI_BI(R1, R0), +- DSB, +- BEQ_MINUS_12 +- }; +- +- aice_write_dtr(coreid, data); +- aice_execute_dim(coreid, instructions, 4); +- +- return ERROR_OK; +-} +- +-static int aice_usb_write_memory_unit(uint32_t coreid, uint32_t addr, uint32_t size, +- uint32_t count, const uint8_t *buffer) +-{ +- LOG_DEBUG("aice_usb_write_memory_unit, addr: 0x%08" PRIx32 +- ", size: %" PRIu32 ", count: %" PRIu32 "", +- addr, size, count); +- +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) +- aice_usb_set_address_dim(coreid, addr); +- +- size_t i; +- write_mem_func_t write_mem_func; +- +- switch (size) { +- case 1: +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) +- write_mem_func = aice_usb_write_mem_b_bus; +- else +- write_mem_func = aice_usb_write_mem_b_dim; +- +- for (i = 0; i < count; i++) { +- write_mem_func(coreid, addr, *buffer); +- buffer++; +- addr++; +- } +- break; +- case 2: +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) +- write_mem_func = aice_usb_write_mem_h_bus; +- else +- write_mem_func = aice_usb_write_mem_h_dim; +- +- for (i = 0; i < count; i++) { +- uint16_t value; +- memcpy(&value, buffer, sizeof(uint16_t)); +- +- write_mem_func(coreid, addr, value); +- buffer += 2; +- addr += 2; +- } +- break; +- case 4: +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) +- write_mem_func = aice_usb_write_mem_w_bus; +- else +- write_mem_func = aice_usb_write_mem_w_dim; +- +- for (i = 0; i < count; i++) { +- uint32_t value; +- memcpy(&value, buffer, sizeof(uint32_t)); +- +- write_mem_func(coreid, addr, value); +- buffer += 4; +- addr += 4; +- } +- break; +- } +- +- return ERROR_OK; +-} +- +-static int aice_bulk_read_mem(uint32_t coreid, uint32_t addr, uint32_t count, +- uint8_t *buffer) +-{ +- uint32_t packet_size; +- +- while (count > 0) { +- packet_size = (count >= 0x100) ? 0x100 : count; +- +- /** set address */ +- addr &= 0xFFFFFFFC; +- if (aice_write_misc(coreid, NDS_EDM_MISC_SBAR, addr) != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_fastread_mem(coreid, buffer, +- packet_size) != ERROR_OK) +- return ERROR_FAIL; +- +- buffer += (packet_size * 4); +- addr += (packet_size * 4); +- count -= packet_size; +- } +- +- return ERROR_OK; +-} +- +-static int aice_bulk_write_mem(uint32_t coreid, uint32_t addr, uint32_t count, +- const uint8_t *buffer) +-{ +- uint32_t packet_size; +- +- while (count > 0) { +- packet_size = (count >= 0x100) ? 0x100 : count; +- +- /** set address */ +- addr &= 0xFFFFFFFC; +- if (aice_write_misc(coreid, NDS_EDM_MISC_SBAR, addr | 1) != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_fastwrite_mem(coreid, buffer, +- packet_size) != ERROR_OK) +- return ERROR_FAIL; +- +- buffer += (packet_size * 4); +- addr += (packet_size * 4); +- count -= packet_size; +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_bulk_read_mem(uint32_t coreid, uint32_t addr, +- uint32_t length, uint8_t *buffer) +-{ +- LOG_DEBUG("aice_usb_bulk_read_mem, addr: 0x%08" PRIx32 ", length: 0x%08" PRIx32, addr, length); +- +- int retval; +- +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) +- aice_usb_set_address_dim(coreid, addr); +- +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) +- retval = aice_usb_read_memory_unit(coreid, addr, 4, length / 4, buffer); +- else +- retval = aice_bulk_read_mem(coreid, addr, length / 4, buffer); +- +- return retval; +-} +- +-static int aice_usb_bulk_write_mem(uint32_t coreid, uint32_t addr, +- uint32_t length, const uint8_t *buffer) +-{ +- LOG_DEBUG("aice_usb_bulk_write_mem, addr: 0x%08" PRIx32 ", length: 0x%08" PRIx32, addr, length); +- +- int retval; +- +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) +- aice_usb_set_address_dim(coreid, addr); +- +- if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) +- retval = aice_usb_write_memory_unit(coreid, addr, 4, length / 4, buffer); +- else +- retval = aice_bulk_write_mem(coreid, addr, length / 4, buffer); +- +- return retval; +-} +- +-static int aice_usb_read_debug_reg(uint32_t coreid, uint32_t addr, uint32_t *val) +-{ +- if (core_info[coreid].core_state == AICE_TARGET_HALTED) { +- if (addr == NDS_EDM_SR_EDMSW) { +- *val = core_info[coreid].edmsw_backup; +- } else if (addr == NDS_EDM_SR_EDM_DTR) { +- if (core_info[coreid].target_dtr_valid) { +- /* if EDM_DTR has read out, clear it. */ +- *val = core_info[coreid].target_dtr_backup; +- core_info[coreid].edmsw_backup &= (~0x1); +- core_info[coreid].target_dtr_valid = false; +- } else { +- *val = 0; +- } +- } +- } +- +- return aice_read_edmsr(coreid, addr, val); +-} +- +-static int aice_usb_write_debug_reg(uint32_t coreid, uint32_t addr, const uint32_t val) +-{ +- if (core_info[coreid].core_state == AICE_TARGET_HALTED) { +- if (addr == NDS_EDM_SR_EDM_DTR) { +- core_info[coreid].host_dtr_backup = val; +- core_info[coreid].edmsw_backup |= 0x2; +- core_info[coreid].host_dtr_valid = true; +- } +- } +- +- return aice_write_edmsr(coreid, addr, val); +-} +- +-static int aice_usb_memory_access(uint32_t coreid, enum nds_memory_access channel) +-{ +- LOG_DEBUG("aice_usb_memory_access, access channel: %u", channel); +- +- core_info[coreid].access_channel = channel; +- +- return ERROR_OK; +-} +- +-static int aice_usb_memory_mode(uint32_t coreid, enum nds_memory_select mem_select) +-{ +- if (core_info[coreid].memory_select == mem_select) +- return ERROR_OK; +- +- LOG_DEBUG("aice_usb_memory_mode, memory select: %u", mem_select); +- +- core_info[coreid].memory_select = mem_select; +- +- if (core_info[coreid].memory_select != NDS_MEMORY_SELECT_AUTO) +- aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, +- core_info[coreid].memory_select - 1); +- else +- aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, +- NDS_MEMORY_SELECT_MEM - 1); +- +- return ERROR_OK; +-} +- +-static int aice_usb_read_tlb(uint32_t coreid, target_addr_t virtual_address, +- target_addr_t *physical_address) +-{ +- LOG_DEBUG("aice_usb_read_tlb, virtual address: 0x%08" TARGET_PRIxADDR, virtual_address); +- +- uint32_t instructions[4]; +- uint32_t probe_result; +- uint32_t value_mr3; +- uint32_t value_mr4; +- uint32_t access_page_size; +- uint32_t virtual_offset; +- uint32_t physical_page_number; +- +- aice_write_dtr(coreid, virtual_address); +- +- /* probe TLB first */ +- instructions[0] = MFSR_DTR(R0); +- instructions[1] = TLBOP_TARGET_PROBE(R1, R0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- aice_execute_dim(coreid, instructions, 4); +- +- aice_read_reg(coreid, R1, &probe_result); +- +- if (probe_result & 0x80000000) +- return ERROR_FAIL; +- +- /* read TLB entry */ +- aice_write_dtr(coreid, probe_result & 0x7FF); +- +- /* probe TLB first */ +- instructions[0] = MFSR_DTR(R0); +- instructions[1] = TLBOP_TARGET_READ(R0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- aice_execute_dim(coreid, instructions, 4); +- +- /* TODO: it should backup mr3, mr4 */ +- aice_read_reg(coreid, MR3, &value_mr3); +- aice_read_reg(coreid, MR4, &value_mr4); +- +- access_page_size = value_mr4 & 0xF; +- if (access_page_size == 0) { /* 4K page */ +- virtual_offset = virtual_address & 0x00000FFF; +- physical_page_number = value_mr3 & 0xFFFFF000; +- } else if (access_page_size == 1) { /* 8K page */ +- virtual_offset = virtual_address & 0x00001FFF; +- physical_page_number = value_mr3 & 0xFFFFE000; +- } else if (access_page_size == 5) { /* 1M page */ +- virtual_offset = virtual_address & 0x000FFFFF; +- physical_page_number = value_mr3 & 0xFFF00000; +- } else { +- return ERROR_FAIL; +- } +- +- *physical_address = physical_page_number | virtual_offset; +- +- return ERROR_OK; +-} +- +-static int aice_usb_init_cache(uint32_t coreid) +-{ +- LOG_DEBUG("aice_usb_init_cache"); +- +- uint32_t value_cr1; +- uint32_t value_cr2; +- +- aice_read_reg(coreid, CR1, &value_cr1); +- aice_read_reg(coreid, CR2, &value_cr2); +- +- struct cache_info *icache = &core_info[coreid].icache; +- +- icache->set = value_cr1 & 0x7; +- icache->log2_set = icache->set + 6; +- icache->set = 64 << icache->set; +- icache->way = ((value_cr1 >> 3) & 0x7) + 1; +- icache->line_size = (value_cr1 >> 6) & 0x7; +- if (icache->line_size != 0) { +- icache->log2_line_size = icache->line_size + 2; +- icache->line_size = 8 << (icache->line_size - 1); +- } else { +- icache->log2_line_size = 0; +- } +- +- LOG_DEBUG("\ticache set: %" PRIu32 ", way: %" PRIu32 ", line size: %" PRIu32 ", " +- "log2(set): %" PRIu32 ", log2(line_size): %" PRIu32 "", +- icache->set, icache->way, icache->line_size, +- icache->log2_set, icache->log2_line_size); +- +- struct cache_info *dcache = &core_info[coreid].dcache; +- +- dcache->set = value_cr2 & 0x7; +- dcache->log2_set = dcache->set + 6; +- dcache->set = 64 << dcache->set; +- dcache->way = ((value_cr2 >> 3) & 0x7) + 1; +- dcache->line_size = (value_cr2 >> 6) & 0x7; +- if (dcache->line_size != 0) { +- dcache->log2_line_size = dcache->line_size + 2; +- dcache->line_size = 8 << (dcache->line_size - 1); +- } else { +- dcache->log2_line_size = 0; +- } +- +- LOG_DEBUG("\tdcache set: %" PRIu32 ", way: %" PRIu32 ", line size: %" PRIu32 ", " +- "log2(set): %" PRIu32 ", log2(line_size): %" PRIu32 "", +- dcache->set, dcache->way, dcache->line_size, +- dcache->log2_set, dcache->log2_line_size); +- +- core_info[coreid].cache_init = true; +- +- return ERROR_OK; +-} +- +-static int aice_usb_dcache_inval_all(uint32_t coreid) +-{ +- LOG_DEBUG("aice_usb_dcache_inval_all"); +- +- uint32_t set_index; +- uint32_t way_index; +- uint32_t cache_index; +- uint32_t instructions[4]; +- +- instructions[0] = MFSR_DTR(R0); +- instructions[1] = L1D_IX_INVAL(R0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- +- struct cache_info *dcache = &core_info[coreid].dcache; +- +- for (set_index = 0; set_index < dcache->set; set_index++) { +- for (way_index = 0; way_index < dcache->way; way_index++) { +- cache_index = (way_index << (dcache->log2_set + dcache->log2_line_size)) | +- (set_index << dcache->log2_line_size); +- +- if (aice_write_dtr(coreid, cache_index) != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK) +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_dcache_va_inval(uint32_t coreid, uint32_t address) +-{ +- LOG_DEBUG("aice_usb_dcache_va_inval"); +- +- uint32_t instructions[4]; +- +- aice_write_dtr(coreid, address); +- +- instructions[0] = MFSR_DTR(R0); +- instructions[1] = L1D_VA_INVAL(R0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- +- return aice_execute_dim(coreid, instructions, 4); +-} +- +-static int aice_usb_dcache_wb_all(uint32_t coreid) +-{ +- LOG_DEBUG("aice_usb_dcache_wb_all"); +- +- uint32_t set_index; +- uint32_t way_index; +- uint32_t cache_index; +- uint32_t instructions[4]; +- +- instructions[0] = MFSR_DTR(R0); +- instructions[1] = L1D_IX_WB(R0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- +- struct cache_info *dcache = &core_info[coreid].dcache; +- +- for (set_index = 0; set_index < dcache->set; set_index++) { +- for (way_index = 0; way_index < dcache->way; way_index++) { +- cache_index = (way_index << (dcache->log2_set + dcache->log2_line_size)) | +- (set_index << dcache->log2_line_size); +- +- if (aice_write_dtr(coreid, cache_index) != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK) +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_dcache_va_wb(uint32_t coreid, uint32_t address) +-{ +- LOG_DEBUG("aice_usb_dcache_va_wb"); +- +- uint32_t instructions[4]; +- +- aice_write_dtr(coreid, address); +- +- instructions[0] = MFSR_DTR(R0); +- instructions[1] = L1D_VA_WB(R0); +- instructions[2] = DSB; +- instructions[3] = BEQ_MINUS_12; +- +- return aice_execute_dim(coreid, instructions, 4); +-} +- +-static int aice_usb_icache_inval_all(uint32_t coreid) +-{ +- LOG_DEBUG("aice_usb_icache_inval_all"); +- +- uint32_t set_index; +- uint32_t way_index; +- uint32_t cache_index; +- uint32_t instructions[4]; +- +- instructions[0] = MFSR_DTR(R0); +- instructions[1] = L1I_IX_INVAL(R0); +- instructions[2] = ISB; +- instructions[3] = BEQ_MINUS_12; +- +- struct cache_info *icache = &core_info[coreid].icache; +- +- for (set_index = 0; set_index < icache->set; set_index++) { +- for (way_index = 0; way_index < icache->way; way_index++) { +- cache_index = (way_index << (icache->log2_set + icache->log2_line_size)) | +- (set_index << icache->log2_line_size); +- +- if (aice_write_dtr(coreid, cache_index) != ERROR_OK) +- return ERROR_FAIL; +- +- if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK) +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_icache_va_inval(uint32_t coreid, uint32_t address) +-{ +- LOG_DEBUG("aice_usb_icache_va_inval"); +- +- uint32_t instructions[4]; +- +- aice_write_dtr(coreid, address); +- +- instructions[0] = MFSR_DTR(R0); +- instructions[1] = L1I_VA_INVAL(R0); +- instructions[2] = ISB; +- instructions[3] = BEQ_MINUS_12; +- +- return aice_execute_dim(coreid, instructions, 4); +-} +- +-static int aice_usb_cache_ctl(uint32_t coreid, uint32_t subtype, uint32_t address) +-{ +- LOG_DEBUG("aice_usb_cache_ctl"); +- +- int result; +- +- if (core_info[coreid].cache_init == false) +- aice_usb_init_cache(coreid); +- +- switch (subtype) { +- case AICE_CACHE_CTL_L1D_INVALALL: +- result = aice_usb_dcache_inval_all(coreid); +- break; +- case AICE_CACHE_CTL_L1D_VA_INVAL: +- result = aice_usb_dcache_va_inval(coreid, address); +- break; +- case AICE_CACHE_CTL_L1D_WBALL: +- result = aice_usb_dcache_wb_all(coreid); +- break; +- case AICE_CACHE_CTL_L1D_VA_WB: +- result = aice_usb_dcache_va_wb(coreid, address); +- break; +- case AICE_CACHE_CTL_L1I_INVALALL: +- result = aice_usb_icache_inval_all(coreid); +- break; +- case AICE_CACHE_CTL_L1I_VA_INVAL: +- result = aice_usb_icache_va_inval(coreid, address); +- break; +- default: +- result = ERROR_FAIL; +- break; +- } +- +- return result; +-} +- +-static int aice_usb_set_retry_times(uint32_t a_retry_times) +-{ +- aice_max_retry_times = a_retry_times; +- return ERROR_OK; +-} +- +-static int aice_usb_program_edm(uint32_t coreid, char *command_sequence) +-{ +- char *command_str; +- char *reg_name_0; +- char *reg_name_1; +- uint32_t data_value; +- int i; +- +- /* init strtok() */ +- command_str = strtok(command_sequence, ";"); +- if (!command_str) +- return ERROR_OK; +- +- do { +- i = 0; +- /* process one command */ +- while (command_str[i] == ' ' || +- command_str[i] == '\n' || +- command_str[i] == '\r' || +- command_str[i] == '\t') +- i++; +- +- /* skip ' ', '\r', '\n', '\t' */ +- command_str = command_str + i; +- +- if (strncmp(command_str, "write_misc", 10) == 0) { +- reg_name_0 = strstr(command_str, "gen_port0"); +- reg_name_1 = strstr(command_str, "gen_port1"); +- +- if (reg_name_0) { +- data_value = strtoul(reg_name_0 + 9, NULL, 0); +- +- if (aice_write_misc(coreid, +- NDS_EDM_MISC_GEN_PORT0, data_value) != ERROR_OK) +- return ERROR_FAIL; +- +- } else if (reg_name_1) { +- data_value = strtoul(reg_name_1 + 9, NULL, 0); +- +- if (aice_write_misc(coreid, +- NDS_EDM_MISC_GEN_PORT1, data_value) != ERROR_OK) +- return ERROR_FAIL; +- } else { +- LOG_ERROR("program EDM, unsupported misc register: %s", command_str); +- } +- } else { +- LOG_ERROR("program EDM, unsupported command: %s", command_str); +- } +- +- /* update command_str */ +- command_str = strtok(NULL, ";"); +- +- } while (command_str); +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_command_mode(enum aice_command_mode command_mode) +-{ +- int retval = ERROR_OK; +- +- /* flush usb_packets_buffer as users change mode */ +- retval = aice_usb_packet_flush(); +- +- if (command_mode == AICE_COMMAND_MODE_BATCH) { +- /* reset batch buffer */ +- aice_command_mode = AICE_COMMAND_MODE_NORMAL; +- retval = aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CMD_BUF0_CTRL, 0x40000); +- } +- +- aice_command_mode = command_mode; +- +- return retval; +-} +- +-static int aice_usb_execute(uint32_t coreid, uint32_t *instructions, +- uint32_t instruction_num) +-{ +- uint32_t i, j; +- uint8_t current_instruction_num; +- uint32_t dim_instructions[4] = {NOP, NOP, NOP, BEQ_MINUS_12}; +- +- /* To execute 4 instructions as a special case */ +- if (instruction_num == 4) +- return aice_execute_dim(coreid, instructions, 4); +- +- for (i = 0 ; i < instruction_num ; i += 3) { +- if (instruction_num - i < 3) { +- current_instruction_num = instruction_num - i; +- for (j = current_instruction_num ; j < 3 ; j++) +- dim_instructions[j] = NOP; +- } else { +- current_instruction_num = 3; +- } +- +- memcpy(dim_instructions, instructions + i, +- current_instruction_num * sizeof(uint32_t)); +- +- /** fill DIM */ +- if (aice_write_dim(coreid, +- dim_instructions, +- 4) != ERROR_OK) +- return ERROR_FAIL; +- +- /** clear DBGER.DPED */ +- if (aice_write_misc(coreid, +- NDS_EDM_MISC_DBGER, NDS_DBGER_DPED) != ERROR_OK) +- return ERROR_FAIL; +- +- /** execute DIM */ +- if (aice_do_execute(coreid) != ERROR_OK) +- return ERROR_FAIL; +- +- /** check DBGER.DPED */ +- if (aice_check_dbger(coreid, NDS_DBGER_DPED) != ERROR_OK) { +- +- LOG_ERROR("<-- TARGET ERROR! Debug operations do not finish properly:" +- "0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 ". -->", +- dim_instructions[0], +- dim_instructions[1], +- dim_instructions[2], +- dim_instructions[3]); +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_custom_srst_script(const char *script) +-{ +- custom_srst_script = strdup(script); +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_custom_trst_script(const char *script) +-{ +- custom_trst_script = strdup(script); +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_custom_restart_script(const char *script) +-{ +- custom_restart_script = strdup(script); +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_count_to_check_dbger(uint32_t count_to_check) +-{ +- aice_count_to_check_dbger = count_to_check; +- +- return ERROR_OK; +-} +- +-static int aice_usb_set_data_endian(uint32_t coreid, +- enum aice_target_endian target_data_endian) +-{ +- data_endian = target_data_endian; +- +- return ERROR_OK; +-} +- +-static int fill_profiling_batch_commands(uint32_t coreid, uint32_t reg_no) +-{ +- uint32_t dim_instructions[4]; +- +- aice_usb_set_command_mode(AICE_COMMAND_MODE_BATCH); +- +- /* halt */ +- if (aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0) != ERROR_OK) +- return ERROR_FAIL; +- +- /* backup $r0 */ +- dim_instructions[0] = MTSR_DTR(0); +- dim_instructions[1] = DSB; +- dim_instructions[2] = NOP; +- dim_instructions[3] = BEQ_MINUS_12; +- if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) +- return ERROR_FAIL; +- aice_read_dtr_to_buffer(coreid, AICE_BATCH_DATA_BUFFER_0); +- +- /* get samples */ +- if (nds32_reg_type(reg_no) == NDS32_REG_TYPE_GPR) { +- /* general registers */ +- dim_instructions[0] = MTSR_DTR(reg_no); +- dim_instructions[1] = DSB; +- dim_instructions[2] = NOP; +- dim_instructions[3] = BEQ_MINUS_12; +- } else if (nds32_reg_type(reg_no) == NDS32_REG_TYPE_SPR) { +- /* user special registers */ +- dim_instructions[0] = MFUSR_G0(0, nds32_reg_sr_index(reg_no)); +- dim_instructions[1] = MTSR_DTR(0); +- dim_instructions[2] = DSB; +- dim_instructions[3] = BEQ_MINUS_12; +- } else { /* system registers */ +- dim_instructions[0] = MFSR(0, nds32_reg_sr_index(reg_no)); +- dim_instructions[1] = MTSR_DTR(0); +- dim_instructions[2] = DSB; +- dim_instructions[3] = BEQ_MINUS_12; +- } +- if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) +- return ERROR_FAIL; +- aice_read_dtr_to_buffer(coreid, AICE_BATCH_DATA_BUFFER_1); +- +- /* restore $r0 */ +- aice_write_dtr_from_buffer(coreid, AICE_BATCH_DATA_BUFFER_0); +- dim_instructions[0] = MFSR_DTR(0); +- dim_instructions[1] = DSB; +- dim_instructions[2] = NOP; +- dim_instructions[3] = IRET; /* free run */ +- if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) +- return ERROR_FAIL; +- +- aice_command_mode = AICE_COMMAND_MODE_NORMAL; +- +- /* use BATCH_BUFFER_WRITE to fill command-batch-buffer */ +- if (aice_batch_buffer_write(AICE_BATCH_COMMAND_BUFFER_0, +- usb_out_packets_buffer, +- (usb_out_packets_buffer_length + 3) / 4) != ERROR_OK) +- return ERROR_FAIL; +- +- usb_out_packets_buffer_length = 0; +- usb_in_packets_buffer_length = 0; +- +- return ERROR_OK; +-} +- +-static int aice_usb_profiling(uint32_t coreid, uint32_t interval, uint32_t iteration, +- uint32_t reg_no, uint32_t *samples, uint32_t *num_samples) +-{ +- uint32_t iteration_count; +- uint32_t this_iteration; +- int retval = ERROR_OK; +- const uint32_t MAX_ITERATION = 250; +- +- *num_samples = 0; +- +- /* init DIM size */ +- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DIM_SIZE, 4) != ERROR_OK) +- return ERROR_FAIL; +- +- /* Use AICE_BATCH_DATA_BUFFER_0 to read/write $DTR. +- * Set it to circular buffer */ +- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DATA_BUF0_CTRL, 0xC0000) != ERROR_OK) +- return ERROR_FAIL; +- +- fill_profiling_batch_commands(coreid, reg_no); +- +- iteration_count = 0; +- while (iteration_count < iteration) { +- if (iteration - iteration_count < MAX_ITERATION) +- this_iteration = iteration - iteration_count; +- else +- this_iteration = MAX_ITERATION; +- +- /* set number of iterations */ +- uint32_t val_iteration; +- val_iteration = interval << 16 | this_iteration; +- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_ITERATION, +- val_iteration) != ERROR_OK) { +- retval = ERROR_FAIL; +- goto end_profiling; +- } +- +- /* init AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL to store $PC */ +- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL, +- 0x40000) != ERROR_OK) { +- retval = ERROR_FAIL; +- goto end_profiling; +- } +- +- aice_usb_run(coreid); +- +- /* enable BATCH command */ +- if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CTRL, +- 0x80000000) != ERROR_OK) { +- aice_usb_halt(coreid); +- retval = ERROR_FAIL; +- goto end_profiling; +- } +- +- /* wait a while (AICE bug, workaround) */ +- alive_sleep(this_iteration); +- +- /* check status */ +- uint32_t i; +- uint32_t batch_status = 0; +- +- i = 0; +- while (1) { +- aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status); +- +- if (batch_status & 0x1) { +- break; +- } else if (batch_status & 0xE) { +- aice_usb_halt(coreid); +- retval = ERROR_FAIL; +- goto end_profiling; +- } +- +- if ((i % 30) == 0) +- keep_alive(); +- +- i++; +- } +- +- aice_usb_halt(coreid); +- +- /* get samples from batch data buffer */ +- if (aice_batch_buffer_read(AICE_BATCH_DATA_BUFFER_1, +- samples + iteration_count, this_iteration) != ERROR_OK) { +- retval = ERROR_FAIL; +- goto end_profiling; +- } +- +- iteration_count += this_iteration; +- } +- +-end_profiling: +- *num_samples = iteration_count; +- +- return retval; +-} +- +-/** */ +-struct aice_port_api_s aice_usb_api = { +- /** */ +- .open = aice_open_device, +- /** */ +- .close = aice_usb_close, +- /** */ +- .idcode = aice_usb_idcode, +- /** */ +- .state = aice_usb_state, +- /** */ +- .reset = aice_usb_reset, +- /** */ +- .assert_srst = aice_usb_assert_srst, +- /** */ +- .run = aice_usb_run, +- /** */ +- .halt = aice_usb_halt, +- /** */ +- .step = aice_usb_step, +- /** */ +- .read_reg = aice_usb_read_reg, +- /** */ +- .write_reg = aice_usb_write_reg, +- /** */ +- .read_reg_64 = aice_usb_read_reg_64, +- /** */ +- .write_reg_64 = aice_usb_write_reg_64, +- /** */ +- .read_mem_unit = aice_usb_read_memory_unit, +- /** */ +- .write_mem_unit = aice_usb_write_memory_unit, +- /** */ +- .read_mem_bulk = aice_usb_bulk_read_mem, +- /** */ +- .write_mem_bulk = aice_usb_bulk_write_mem, +- /** */ +- .read_debug_reg = aice_usb_read_debug_reg, +- /** */ +- .write_debug_reg = aice_usb_write_debug_reg, +- /** */ +- .set_jtag_clock = aice_usb_set_jtag_clock, +- /** */ +- .memory_access = aice_usb_memory_access, +- /** */ +- .memory_mode = aice_usb_memory_mode, +- /** */ +- .read_tlb = aice_usb_read_tlb, +- /** */ +- .cache_ctl = aice_usb_cache_ctl, +- /** */ +- .set_retry_times = aice_usb_set_retry_times, +- /** */ +- .program_edm = aice_usb_program_edm, +- /** */ +- .set_command_mode = aice_usb_set_command_mode, +- /** */ +- .execute = aice_usb_execute, +- /** */ +- .set_custom_srst_script = aice_usb_set_custom_srst_script, +- /** */ +- .set_custom_trst_script = aice_usb_set_custom_trst_script, +- /** */ +- .set_custom_restart_script = aice_usb_set_custom_restart_script, +- /** */ +- .set_count_to_check_dbger = aice_usb_set_count_to_check_dbger, +- /** */ +- .set_data_endian = aice_usb_set_data_endian, +- /** */ +- .profiling = aice_usb_profiling, +-}; +diff --git a/src/jtag/aice/aice_usb.h b/src/jtag/aice/aice_usb.h +deleted file mode 100644 +index d85d25f89..000000000 +--- a/src/jtag/aice/aice_usb.h ++++ /dev/null +@@ -1,122 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 by Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_JTAG_AICE_AICE_USB_H +-#define OPENOCD_JTAG_AICE_AICE_USB_H +- +-#include "aice_port.h" +- +-/* AICE USB timeout value */ +-#define AICE_USB_TIMEOUT 5000 +- +-/* AICE USB buffer size */ +-#define AICE_IN_BUFFER_SIZE 2048 +-#define AICE_OUT_BUFFER_SIZE 2048 +-#define AICE_IN_PACKETS_BUFFER_SIZE 2048 +-#define AICE_OUT_PACKETS_BUFFER_SIZE 2048 +-#define AICE_IN_BATCH_COMMAND_SIZE 512 +-#define AICE_OUT_BATCH_COMMAND_SIZE 512 +-#define AICE_IN_PACK_COMMAND_SIZE 2048 +-#define AICE_OUT_PACK_COMMAND_SIZE 2048 +- +-/* Constants for AICE command READ_CTRL */ +-#define AICE_READ_CTRL_GET_ICE_STATE 0x00 +-#define AICE_READ_CTRL_GET_HARDWARE_VERSION 0x01 +-#define AICE_READ_CTRL_GET_FPGA_VERSION 0x02 +-#define AICE_READ_CTRL_GET_FIRMWARE_VERSION 0x03 +-#define AICE_READ_CTRL_GET_JTAG_PIN_STATUS 0x04 +-#define AICE_READ_CTRL_BATCH_BUF_INFO 0x22 +-#define AICE_READ_CTRL_BATCH_STATUS 0x23 +-#define AICE_READ_CTRL_BATCH_BUF0_STATE 0x31 +-#define AICE_READ_CTRL_BATCH_BUF4_STATE 0x39 +-#define AICE_READ_CTRL_BATCH_BUF5_STATE 0x3b +- +-/* Constants for AICE command WRITE_CTRL */ +-#define AICE_WRITE_CTRL_TCK_CONTROL 0x00 +-#define AICE_WRITE_CTRL_JTAG_PIN_CONTROL 0x01 +-#define AICE_WRITE_CTRL_CLEAR_TIMEOUT_STATUS 0x02 +-#define AICE_WRITE_CTRL_RESERVED 0x03 +-#define AICE_WRITE_CTRL_JTAG_PIN_STATUS 0x04 +-#define AICE_WRITE_CTRL_CUSTOM_DELAY 0x0d +-#define AICE_WRITE_CTRL_BATCH_CTRL 0x20 +-#define AICE_WRITE_CTRL_BATCH_ITERATION 0x21 +-#define AICE_WRITE_CTRL_BATCH_DIM_SIZE 0x22 +-#define AICE_WRITE_CTRL_BATCH_CMD_BUF0_CTRL 0x30 +-#define AICE_WRITE_CTRL_BATCH_DATA_BUF0_CTRL 0x38 +-#define AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL 0x3a +- +-#define AICE_BATCH_COMMAND_BUFFER_0 0x0 +-#define AICE_BATCH_COMMAND_BUFFER_1 0x1 +-#define AICE_BATCH_COMMAND_BUFFER_2 0x2 +-#define AICE_BATCH_COMMAND_BUFFER_3 0x3 +-#define AICE_BATCH_DATA_BUFFER_0 0x4 +-#define AICE_BATCH_DATA_BUFFER_1 0x5 +-#define AICE_BATCH_DATA_BUFFER_2 0x6 +-#define AICE_BATCH_DATA_BUFFER_3 0x7 +- +-/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */ +-#define AICE_TCK_CONTROL_TCK3048 0x08 +-#define AICE_TCK_CONTROL_TCK_SCAN 0x10 +- +-/* Constants for AICE command WRITE_CTRL:JTAG_PIN_CONTROL */ +-#define AICE_JTAG_PIN_CONTROL_SRST 0x01 +-#define AICE_JTAG_PIN_CONTROL_TRST 0x02 +-#define AICE_JTAG_PIN_CONTROL_STOP 0x04 +-#define AICE_JTAG_PIN_CONTROL_RESTART 0x08 +- +-/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */ +-#define AICE_TCK_CONTROL_TCK_SCAN 0x10 +- +-/* Custom SRST/DBGI/TRST */ +-#define AICE_CUSTOM_DELAY_SET_SRST 0x01 +-#define AICE_CUSTOM_DELAY_CLEAN_SRST 0x02 +-#define AICE_CUSTOM_DELAY_SET_DBGI 0x04 +-#define AICE_CUSTOM_DELAY_CLEAN_DBGI 0x08 +-#define AICE_CUSTOM_DELAY_SET_TRST 0x10 +-#define AICE_CUSTOM_DELAY_CLEAN_TRST 0x20 +- +-struct aice_usb_handler_s { +- unsigned int usb_read_ep; +- unsigned int usb_write_ep; +- struct libusb_device_handle *usb_handle; +-}; +- +-struct cache_info { +- uint32_t set; +- uint32_t way; +- uint32_t line_size; +- +- uint32_t log2_set; +- uint32_t log2_line_size; +-}; +- +-struct aice_nds32_info { +- uint32_t edm_version; +- uint32_t r0_backup; +- uint32_t r1_backup; +- uint32_t host_dtr_backup; +- uint32_t target_dtr_backup; +- uint32_t edmsw_backup; +- uint32_t edm_ctl_backup; +- bool debug_under_dex_on; +- bool dex_use_psw_on; +- bool host_dtr_valid; +- bool target_dtr_valid; +- enum nds_memory_access access_channel; +- enum nds_memory_select memory_select; +- enum aice_target_state_s core_state; +- bool cache_init; +- struct cache_info icache; +- struct cache_info dcache; +-}; +- +-extern struct aice_port_api_s aice_usb_api; +- +-int aice_read_ctrl(uint32_t address, uint32_t *data); +-int aice_write_ctrl(uint32_t address, uint32_t data); +- +-#endif /* OPENOCD_JTAG_AICE_AICE_USB_H */ +diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c +index 67bbb3b36..12848be03 100644 +--- a/src/jtag/interfaces.c ++++ b/src/jtag/interfaces.c +@@ -118,9 +118,6 @@ extern struct adapter_driver linuxgpiod_adapter_driver; + #if BUILD_XLNX_PCIE_XVC == 1 + extern struct adapter_driver xlnx_pcie_xvc_adapter_driver; + #endif +-#if BUILD_AICE == 1 +-extern struct adapter_driver aice_adapter_driver; +-#endif + #if BUILD_BCM2835GPIO == 1 + extern struct adapter_driver bcm2835gpio_adapter_driver; + #endif +@@ -238,9 +235,6 @@ struct adapter_driver *adapter_drivers[] = { + #if BUILD_XLNX_PCIE_XVC == 1 + &xlnx_pcie_xvc_adapter_driver, + #endif +-#if BUILD_AICE == 1 +- &aice_adapter_driver, +-#endif + #if BUILD_BCM2835GPIO == 1 + &bcm2835gpio_adapter_driver, + #endif +diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl +index aeb42ed4f..b74775a74 100644 +--- a/src/jtag/startup.tcl ++++ b/src/jtag/startup.tcl +@@ -865,12 +865,6 @@ proc ft232r_restore_serial args { + eval ft232r restore_serial $args + } + +-lappend _telnet_autocomplete_skip "aice serial" +-proc "aice serial" {args} { +- echo "DEPRECATED! use 'adapter serial' not 'aice serial'" +- eval adapter serial $args +-} +- + lappend _telnet_autocomplete_skip cmsis_dap_serial + proc cmsis_dap_serial args { + echo "DEPRECATED! use 'adapter serial' not 'cmsis_dap_serial'" +diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c +index 8403a4802..945c4b875 100644 +--- a/src/rtos/FreeRTOS.c ++++ b/src/rtos/FreeRTOS.c +@@ -71,20 +71,6 @@ static const struct freertos_params freertos_params_list[] = { + &rtos_standard_cortex_m4f_stacking, + &rtos_standard_cortex_m4f_fpu_stacking, + }, +- { +- "nds32_v3", /* target_name */ +- 4, /* thread_count_width; */ +- 4, /* pointer_width; */ +- 16, /* list_next_offset; */ +- 20, /* list_width; */ +- 8, /* list_elem_next_offset; */ +- 12, /* list_elem_content_offset */ +- 0, /* thread_stack_offset; */ +- 52, /* thread_name_offset; */ +- &rtos_standard_nds32_n1068_stacking, /* stacking_info */ +- &rtos_standard_cortex_m4f_stacking, +- &rtos_standard_cortex_m4f_fpu_stacking, +- }, + }; + + static bool freertos_detect_rtos(struct target *target); +diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c +index 594511749..f83f0a1fb 100644 +--- a/src/rtos/rtos_standard_stackings.c ++++ b/src/rtos/rtos_standard_stackings.c +@@ -102,45 +102,6 @@ static const struct stack_register_offset rtos_standard_cortex_r4_stack_offsets[ + { 26, 0x04, 32 }, /* CSPR */ + }; + +-static const struct stack_register_offset rtos_standard_nds32_n1068_stack_offsets[] = { +- { 0, 0x88, 32 }, /* R0 */ +- { 1, 0x8C, 32 }, /* R1 */ +- { 2, 0x14, 32 }, /* R2 */ +- { 3, 0x18, 32 }, /* R3 */ +- { 4, 0x1C, 32 }, /* R4 */ +- { 5, 0x20, 32 }, /* R5 */ +- { 6, 0x24, 32 }, /* R6 */ +- { 7, 0x28, 32 }, /* R7 */ +- { 8, 0x2C, 32 }, /* R8 */ +- { 9, 0x30, 32 }, /* R9 */ +- { 10, 0x34, 32 }, /* R10 */ +- { 11, 0x38, 32 }, /* R11 */ +- { 12, 0x3C, 32 }, /* R12 */ +- { 13, 0x40, 32 }, /* R13 */ +- { 14, 0x44, 32 }, /* R14 */ +- { 15, 0x48, 32 }, /* R15 */ +- { 16, 0x4C, 32 }, /* R16 */ +- { 17, 0x50, 32 }, /* R17 */ +- { 18, 0x54, 32 }, /* R18 */ +- { 19, 0x58, 32 }, /* R19 */ +- { 20, 0x5C, 32 }, /* R20 */ +- { 21, 0x60, 32 }, /* R21 */ +- { 22, 0x64, 32 }, /* R22 */ +- { 23, 0x68, 32 }, /* R23 */ +- { 24, 0x6C, 32 }, /* R24 */ +- { 25, 0x70, 32 }, /* R25 */ +- { 26, 0x74, 32 }, /* R26 */ +- { 27, 0x78, 32 }, /* R27 */ +- { 28, 0x7C, 32 }, /* R28 */ +- { 29, 0x80, 32 }, /* R29 */ +- { 30, 0x84, 32 }, /* R30 (LP) */ +- { 31, 0x00, 32 }, /* R31 (SP) */ +- { 32, 0x04, 32 }, /* PSW */ +- { 33, 0x08, 32 }, /* IPC */ +- { 34, 0x0C, 32 }, /* IPSW */ +- { 35, 0x10, 32 }, /* IFC_LP */ +-}; +- + static target_addr_t rtos_generic_stack_align(struct target *target, + const uint8_t *stack_data, const struct rtos_register_stacking *stacking, + target_addr_t stack_ptr, int align) +@@ -268,11 +229,3 @@ const struct rtos_register_stacking rtos_standard_cortex_r4_stacking = { + .calculate_process_stack = rtos_generic_stack_align8, + .register_offsets = rtos_standard_cortex_r4_stack_offsets + }; +- +-const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking = { +- .stack_registers_size = 0x90, +- .stack_growth_direction = -1, +- .num_output_registers = 32, +- .calculate_process_stack = rtos_generic_stack_align8, +- .register_offsets = rtos_standard_nds32_n1068_stack_offsets +-}; +diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h +index 83ca07f9e..2477fffd1 100644 +--- a/src/rtos/rtos_standard_stackings.h ++++ b/src/rtos/rtos_standard_stackings.h +@@ -18,7 +18,6 @@ extern const struct rtos_register_stacking rtos_standard_cortex_m3_stacking; + extern const struct rtos_register_stacking rtos_standard_cortex_m4f_stacking; + extern const struct rtos_register_stacking rtos_standard_cortex_m4f_fpu_stacking; + extern const struct rtos_register_stacking rtos_standard_cortex_r4_stacking; +-extern const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking; + target_addr_t rtos_generic_stack_align8(struct target *target, + const uint8_t *stack_data, const struct rtos_register_stacking *stacking, + target_addr_t stack_ptr); +diff --git a/src/target/Makefile.am b/src/target/Makefile.am +index 46870922a..2084de65e 100644 +--- a/src/target/Makefile.am ++++ b/src/target/Makefile.am +@@ -19,7 +19,6 @@ noinst_LTLIBRARIES += %D%/libtarget.la + $(ARM_MISC_SRC) \ + $(AVR32_SRC) \ + $(MIPS32_SRC) \ +- $(NDS32_SRC) \ + $(STM8_SRC) \ + $(INTEL_IA32_SRC) \ + $(ESIRISC_SRC) \ +@@ -134,18 +133,6 @@ MIPS64_SRC = \ + %D%/trace.c \ + %D%/mips_ejtag.c + +-NDS32_SRC = \ +- %D%/nds32.c \ +- %D%/nds32_reg.c \ +- %D%/nds32_cmd.c \ +- %D%/nds32_disassembler.c \ +- %D%/nds32_tlb.c \ +- %D%/nds32_v2.c \ +- %D%/nds32_v3_common.c \ +- %D%/nds32_v3.c \ +- %D%/nds32_v3m.c \ +- %D%/nds32_aice.c +- + STM8_SRC = \ + %D%/stm8.c + +@@ -235,18 +222,6 @@ ARC_SRC = \ + %D%/avr32_jtag.h \ + %D%/avr32_mem.h \ + %D%/avr32_regs.h \ +- %D%/nds32.h \ +- %D%/nds32_cmd.h \ +- %D%/nds32_disassembler.h \ +- %D%/nds32_edm.h \ +- %D%/nds32_insn.h \ +- %D%/nds32_reg.h \ +- %D%/nds32_tlb.h \ +- %D%/nds32_v2.h \ +- %D%/nds32_v3_common.h \ +- %D%/nds32_v3.h \ +- %D%/nds32_v3m.h \ +- %D%/nds32_aice.h \ + %D%/semihosting_common.h \ + %D%/stm8.h \ + %D%/lakemont.h \ +@@ -265,4 +240,4 @@ ARC_SRC = \ + include %D%/openrisc/Makefile.am + include %D%/riscv/Makefile.am + include %D%/xtensa/Makefile.am +-include %D%/espressif/Makefile.am +\ No newline at end of file ++include %D%/espressif/Makefile.am +diff --git a/src/target/nds32.c b/src/target/nds32.c +deleted file mode 100644 +index bd3097683..000000000 +--- a/src/target/nds32.c ++++ /dev/null +@@ -1,2613 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include +-#include "nds32.h" +-#include "nds32_aice.h" +-#include "nds32_tlb.h" +-#include "nds32_disassembler.h" +- +-struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM]; +-uint32_t nds32_edm_ops_num; +- +-const char *nds32_debug_type_name[11] = { +- "SOFTWARE BREAK", +- "SOFTWARE BREAK_16", +- "HARDWARE BREAKPOINT", +- "DATA ADDR WATCHPOINT PRECISE", +- "DATA VALUE WATCHPOINT PRECISE", +- "DATA VALUE WATCHPOINT IMPRECISE", +- "DEBUG INTERRUPT", +- "HARDWARE SINGLE STEP", +- "DATA ADDR WATCHPOINT NEXT PRECISE", +- "DATA VALUE WATCHPOINT NEXT PRECISE", +- "LOAD STORE GLOBAL STOP", +-}; +- +-static const int nds32_lm_size_table[16] = { +- 4 * 1024, +- 8 * 1024, +- 16 * 1024, +- 32 * 1024, +- 64 * 1024, +- 128 * 1024, +- 256 * 1024, +- 512 * 1024, +- 1024 * 1024, +- 1 * 1024, +- 2 * 1024, +-}; +- +-static const int nds32_line_size_table[6] = { +- 0, +- 8, +- 16, +- 32, +- 64, +- 128, +-}; +- +-static int nds32_get_core_reg(struct reg *reg) +-{ +- int retval; +- struct nds32_reg *reg_arch_info = reg->arch_info; +- struct target *target = reg_arch_info->target; +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- +- if (target->state != TARGET_HALTED) { +- LOG_ERROR("Target not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- if (reg->valid) { +- uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); +- LOG_DEBUG("reading register(cached) %" PRIi32 "(%s), value: 0x%8.8" PRIx32, +- reg_arch_info->num, reg->name, val); +- return ERROR_OK; +- } +- +- int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num); +- +- if (reg_arch_info->enable == false) { +- buf_set_u32(reg_arch_info->value, 0, 32, NDS32_REGISTER_DISABLE); +- retval = ERROR_FAIL; +- } else { +- uint32_t val = 0; +- if ((nds32->fpu_enable == false) +- && (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_FPU)) { +- retval = ERROR_OK; +- } else if ((nds32->audio_enable == false) +- && (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_AUMR)) { +- retval = ERROR_OK; +- } else { +- retval = aice_read_register(aice, mapped_regnum, &val); +- } +- buf_set_u32(reg_arch_info->value, 0, 32, val); +- +- LOG_DEBUG("reading register %" PRIi32 "(%s), value: 0x%8.8" PRIx32, +- reg_arch_info->num, reg->name, val); +- } +- +- if (retval == ERROR_OK) { +- reg->valid = true; +- reg->dirty = false; +- } +- +- return retval; +-} +- +-static int nds32_get_core_reg_64(struct reg *reg) +-{ +- int retval; +- struct nds32_reg *reg_arch_info = reg->arch_info; +- struct target *target = reg_arch_info->target; +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- +- if (target->state != TARGET_HALTED) { +- LOG_ERROR("Target not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- if (reg->valid) +- return ERROR_OK; +- +- if (reg_arch_info->enable == false) { +- buf_set_u64(reg_arch_info->value, 0, 64, NDS32_REGISTER_DISABLE); +- retval = ERROR_FAIL; +- } else { +- uint64_t val = 0; +- if ((nds32->fpu_enable == false) +- && ((reg_arch_info->num >= FD0) && (reg_arch_info->num <= FD31))) { +- retval = ERROR_OK; +- } else { +- retval = aice_read_reg_64(aice, reg_arch_info->num, &val); +- } +- buf_set_u64(reg_arch_info->value, 0, 64, val); +- } +- +- if (retval == ERROR_OK) { +- reg->valid = true; +- reg->dirty = false; +- } +- +- return retval; +-} +- +-static int nds32_update_psw(struct nds32 *nds32) +-{ +- uint32_t value_ir0; +- struct aice_port_s *aice = target_to_aice(nds32->target); +- +- nds32_get_mapped_reg(nds32, IR0, &value_ir0); +- +- /* Save data memory endian */ +- if ((value_ir0 >> 5) & 0x1) { +- nds32->data_endian = TARGET_BIG_ENDIAN; +- aice_set_data_endian(aice, AICE_BIG_ENDIAN); +- } else { +- nds32->data_endian = TARGET_LITTLE_ENDIAN; +- aice_set_data_endian(aice, AICE_LITTLE_ENDIAN); +- } +- +- /* Save translation status */ +- nds32->memory.address_translation = ((value_ir0 >> 7) & 0x1) ? true : false; +- +- return ERROR_OK; +-} +- +-static int nds32_update_mmu_info(struct nds32 *nds32) +-{ +- uint32_t value; +- +- /* Update MMU control status */ +- nds32_get_mapped_reg(nds32, MR0, &value); +- nds32->mmu_config.default_min_page_size = value & 0x1; +- nds32->mmu_config.multiple_page_size_in_use = (value >> 10) & 0x1; +- +- return ERROR_OK; +-} +- +-static int nds32_update_cache_info(struct nds32 *nds32) +-{ +- uint32_t value; +- +- if (nds32_get_mapped_reg(nds32, MR8, &value) == ERROR_OK) { +- if (value & 0x1) +- nds32->memory.icache.enable = true; +- else +- nds32->memory.icache.enable = false; +- +- if (value & 0x2) +- nds32->memory.dcache.enable = true; +- else +- nds32->memory.dcache.enable = false; +- } else { +- nds32->memory.icache.enable = false; +- nds32->memory.dcache.enable = false; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_update_lm_info(struct nds32 *nds32) +-{ +- struct nds32_memory *memory = &(nds32->memory); +- uint32_t value_mr6; +- uint32_t value_mr7; +- +- nds32_get_mapped_reg(nds32, MR6, &value_mr6); +- if (value_mr6 & 0x1) +- memory->ilm_enable = true; +- else +- memory->ilm_enable = false; +- +- if (memory->ilm_align_ver == 0) { /* 1MB aligned */ +- memory->ilm_start = value_mr6 & 0xFFF00000; +- memory->ilm_end = memory->ilm_start + memory->ilm_size; +- } else if (memory->ilm_align_ver == 1) { /* aligned to local memory size */ +- memory->ilm_start = value_mr6 & 0xFFFFFC00; +- memory->ilm_end = memory->ilm_start + memory->ilm_size; +- } else { +- memory->ilm_start = -1; +- memory->ilm_end = -1; +- } +- +- nds32_get_mapped_reg(nds32, MR7, &value_mr7); +- if (value_mr7 & 0x1) +- memory->dlm_enable = true; +- else +- memory->dlm_enable = false; +- +- if (memory->dlm_align_ver == 0) { /* 1MB aligned */ +- memory->dlm_start = value_mr7 & 0xFFF00000; +- memory->dlm_end = memory->dlm_start + memory->dlm_size; +- } else if (memory->dlm_align_ver == 1) { /* aligned to local memory size */ +- memory->dlm_start = value_mr7 & 0xFFFFFC00; +- memory->dlm_end = memory->dlm_start + memory->dlm_size; +- } else { +- memory->dlm_start = -1; +- memory->dlm_end = -1; +- } +- +- return ERROR_OK; +-} +- +-/** +- * If fpu/audio is disabled, to access fpu/audio registers will cause +- * exceptions. So, we need to check if fpu/audio is enabled or not as +- * target is halted. If fpu/audio is disabled, as users access fpu/audio +- * registers, OpenOCD will return fake value 0 instead of accessing +- * registers through DIM. +- */ +-static int nds32_check_extension(struct nds32 *nds32) +-{ +- uint32_t value; +- +- nds32_get_mapped_reg(nds32, FUCPR, &value); +- if (value == NDS32_REGISTER_DISABLE) { +- nds32->fpu_enable = false; +- nds32->audio_enable = false; +- return ERROR_OK; +- } +- +- if (value & 0x1) +- nds32->fpu_enable = true; +- else +- nds32->fpu_enable = false; +- +- if (value & 0x80000000) +- nds32->audio_enable = true; +- else +- nds32->audio_enable = false; +- +- return ERROR_OK; +-} +- +-static int nds32_set_core_reg(struct reg *reg, uint8_t *buf) +-{ +- struct nds32_reg *reg_arch_info = reg->arch_info; +- struct target *target = reg_arch_info->target; +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- uint32_t value = buf_get_u32(buf, 0, 32); +- +- if (target->state != TARGET_HALTED) { +- LOG_ERROR("Target not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num); +- +- /* ignore values that will generate exception */ +- if (nds32_reg_exception(mapped_regnum, value)) +- return ERROR_OK; +- +- LOG_DEBUG("writing register %" PRIi32 "(%s) with value 0x%8.8" PRIx32, +- reg_arch_info->num, reg->name, value); +- +- if ((nds32->fpu_enable == false) && +- (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_FPU)) { +- +- buf_set_u32(reg->value, 0, 32, 0); +- } else if ((nds32->audio_enable == false) && +- (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_AUMR)) { +- +- buf_set_u32(reg->value, 0, 32, 0); +- } else { +- buf_set_u32(reg->value, 0, 32, value); +- uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); +- aice_write_register(aice, mapped_regnum, val); +- +- /* After set value to registers, read the value from target +- * to avoid W1C inconsistency. */ +- aice_read_register(aice, mapped_regnum, &val); +- buf_set_u32(reg_arch_info->value, 0, 32, val); +- } +- +- reg->valid = true; +- reg->dirty = false; +- +- /* update registers to take effect right now */ +- if (mapped_regnum == IR0) { +- nds32_update_psw(nds32); +- } else if (mapped_regnum == MR0) { +- nds32_update_mmu_info(nds32); +- } else if ((mapped_regnum == MR6) || (mapped_regnum == MR7)) { +- /* update lm information */ +- nds32_update_lm_info(nds32); +- } else if (mapped_regnum == MR8) { +- nds32_update_cache_info(nds32); +- } else if (mapped_regnum == FUCPR) { +- /* update audio/fpu setting */ +- nds32_check_extension(nds32); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_set_core_reg_64(struct reg *reg, uint8_t *buf) +-{ +- struct nds32_reg *reg_arch_info = reg->arch_info; +- struct target *target = reg_arch_info->target; +- struct nds32 *nds32 = target_to_nds32(target); +- uint32_t low_part = buf_get_u32(buf, 0, 32); +- uint32_t high_part = buf_get_u32(buf, 32, 32); +- +- if (target->state != TARGET_HALTED) { +- LOG_ERROR("Target not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- if ((nds32->fpu_enable == false) && +- ((reg_arch_info->num >= FD0) && (reg_arch_info->num <= FD31))) { +- +- buf_set_u32(reg->value, 0, 32, 0); +- buf_set_u32(reg->value, 32, 32, 0); +- +- reg->valid = true; +- reg->dirty = false; +- } else { +- buf_set_u32(reg->value, 0, 32, low_part); +- buf_set_u32(reg->value, 32, 32, high_part); +- +- reg->valid = true; +- reg->dirty = true; +- } +- +- return ERROR_OK; +-} +- +-static const struct reg_arch_type nds32_reg_access_type = { +- .get = nds32_get_core_reg, +- .set = nds32_set_core_reg, +-}; +- +-static const struct reg_arch_type nds32_reg_access_type_64 = { +- .get = nds32_get_core_reg_64, +- .set = nds32_set_core_reg_64, +-}; +- +-static struct reg_cache *nds32_build_reg_cache(struct target *target, +- struct nds32 *nds32) +-{ +- struct reg_cache *cache = calloc(sizeof(struct reg_cache), 1); +- struct reg *reg_list = calloc(TOTAL_REG_NUM, sizeof(struct reg)); +- struct nds32_reg *reg_arch_info = calloc(TOTAL_REG_NUM, sizeof(struct nds32_reg)); +- int i; +- +- if (!cache || !reg_list || !reg_arch_info) { +- free(cache); +- free(reg_list); +- free(reg_arch_info); +- return NULL; +- } +- +- cache->name = "Andes registers"; +- cache->next = NULL; +- cache->reg_list = reg_list; +- cache->num_regs = 0; +- +- for (i = 0; i < TOTAL_REG_NUM; i++) { +- reg_arch_info[i].num = i; +- reg_arch_info[i].target = target; +- reg_arch_info[i].nds32 = nds32; +- reg_arch_info[i].enable = false; +- +- reg_list[i].name = nds32_reg_simple_name(i); +- reg_list[i].number = reg_arch_info[i].num; +- reg_list[i].size = nds32_reg_size(i); +- reg_list[i].arch_info = ®_arch_info[i]; +- +- reg_list[i].reg_data_type = calloc(sizeof(struct reg_data_type), 1); +- +- if (reg_arch_info[i].num >= FD0 && reg_arch_info[i].num <= FD31) { +- reg_list[i].value = reg_arch_info[i].value; +- reg_list[i].type = &nds32_reg_access_type_64; +- +- reg_list[i].reg_data_type->type = REG_TYPE_IEEE_DOUBLE; +- reg_list[i].reg_data_type->id = "ieee_double"; +- reg_list[i].group = "float"; +- } else { +- reg_list[i].value = reg_arch_info[i].value; +- reg_list[i].type = &nds32_reg_access_type; +- reg_list[i].group = "general"; +- +- if ((reg_arch_info[i].num >= FS0) && (reg_arch_info[i].num <= FS31)) { +- reg_list[i].reg_data_type->type = REG_TYPE_IEEE_SINGLE; +- reg_list[i].reg_data_type->id = "ieee_single"; +- reg_list[i].group = "float"; +- } else if ((reg_arch_info[i].num == FPCSR) || +- (reg_arch_info[i].num == FPCFG)) { +- reg_list[i].group = "float"; +- } else if ((reg_arch_info[i].num == R28) || +- (reg_arch_info[i].num == R29) || +- (reg_arch_info[i].num == R31)) { +- reg_list[i].reg_data_type->type = REG_TYPE_DATA_PTR; +- reg_list[i].reg_data_type->id = "data_ptr"; +- } else if ((reg_arch_info[i].num == R30) || +- (reg_arch_info[i].num == PC)) { +- reg_list[i].reg_data_type->type = REG_TYPE_CODE_PTR; +- reg_list[i].reg_data_type->id = "code_ptr"; +- } else { +- reg_list[i].reg_data_type->type = REG_TYPE_UINT32; +- reg_list[i].reg_data_type->id = "uint32"; +- } +- } +- +- if (reg_arch_info[i].num >= R16 && reg_arch_info[i].num <= R25) +- reg_list[i].caller_save = true; +- else +- reg_list[i].caller_save = false; +- +- reg_list[i].feature = malloc(sizeof(struct reg_feature)); +- +- if (reg_arch_info[i].num >= R0 && reg_arch_info[i].num <= IFC_LP) +- reg_list[i].feature->name = "org.gnu.gdb.nds32.core"; +- else if (reg_arch_info[i].num >= CR0 && reg_arch_info[i].num <= SECUR0) +- reg_list[i].feature->name = "org.gnu.gdb.nds32.system"; +- else if (reg_arch_info[i].num >= D0L24 && reg_arch_info[i].num <= CBE3) +- reg_list[i].feature->name = "org.gnu.gdb.nds32.audio"; +- else if (reg_arch_info[i].num >= FPCSR && reg_arch_info[i].num <= FD31) +- reg_list[i].feature->name = "org.gnu.gdb.nds32.fpu"; +- +- cache->num_regs++; +- } +- +- nds32->core_cache = cache; +- +- return cache; +-} +- +-static int nds32_reg_cache_init(struct target *target, struct nds32 *nds32) +-{ +- struct reg_cache *cache; +- +- cache = nds32_build_reg_cache(target, nds32); +- if (!cache) +- return ERROR_FAIL; +- +- *register_get_last_cache_p(&target->reg_cache) = cache; +- +- return ERROR_OK; +-} +- +-static struct reg *nds32_reg_current(struct nds32 *nds32, unsigned regnum) +-{ +- struct reg *r; +- +- r = nds32->core_cache->reg_list + regnum; +- +- return r; +-} +- +-int nds32_full_context(struct nds32 *nds32) +-{ +- uint32_t value, value_ir0; +- +- /* save $pc & $psw */ +- nds32_get_mapped_reg(nds32, PC, &value); +- nds32_get_mapped_reg(nds32, IR0, &value_ir0); +- +- nds32_update_psw(nds32); +- nds32_update_mmu_info(nds32); +- nds32_update_cache_info(nds32); +- nds32_update_lm_info(nds32); +- +- nds32_check_extension(nds32); +- +- return ERROR_OK; +-} +- +-/* get register value internally */ +-int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value) +-{ +- struct reg_cache *reg_cache = nds32->core_cache; +- struct reg *r; +- +- if (regnum > reg_cache->num_regs) +- return ERROR_FAIL; +- +- r = nds32_reg_current(nds32, regnum); +- +- if (r->type->get(r) != ERROR_OK) +- return ERROR_FAIL; +- +- *value = buf_get_u32(r->value, 0, 32); +- +- return ERROR_OK; +-} +- +-/** set register internally */ +-int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value) +-{ +- struct reg_cache *reg_cache = nds32->core_cache; +- struct reg *r; +- uint8_t set_value[4]; +- +- if (regnum > reg_cache->num_regs) +- return ERROR_FAIL; +- +- r = nds32_reg_current(nds32, regnum); +- +- buf_set_u32(set_value, 0, 32, value); +- +- return r->type->set(r, set_value); +-} +- +-/** get general register list */ +-static int nds32_get_general_reg_list(struct nds32 *nds32, +- struct reg **reg_list[], int *reg_list_size) +-{ +- struct reg *reg_current; +- int i; +- int current_idx; +- +- /** freed in gdb_server.c */ +- *reg_list = malloc(sizeof(struct reg *) * (IFC_LP - R0 + 1)); +- current_idx = 0; +- +- for (i = R0; i < IFC_LP + 1; i++) { +- reg_current = nds32_reg_current(nds32, i); +- if (((struct nds32_reg *)reg_current->arch_info)->enable) { +- (*reg_list)[current_idx] = reg_current; +- current_idx++; +- } +- } +- *reg_list_size = current_idx; +- +- return ERROR_OK; +-} +- +-/** get all register list */ +-static int nds32_get_all_reg_list(struct nds32 *nds32, +- struct reg **reg_list[], int *reg_list_size) +-{ +- struct reg_cache *reg_cache = nds32->core_cache; +- struct reg *reg_current; +- unsigned int i; +- +- *reg_list_size = reg_cache->num_regs; +- +- /** freed in gdb_server.c */ +- *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); +- +- for (i = 0; i < reg_cache->num_regs; i++) { +- reg_current = nds32_reg_current(nds32, i); +- reg_current->exist = ((struct nds32_reg *) +- reg_current->arch_info)->enable; +- (*reg_list)[i] = reg_current; +- } +- +- return ERROR_OK; +-} +- +-/** get all register list */ +-int nds32_get_gdb_reg_list(struct target *target, +- struct reg **reg_list[], int *reg_list_size, +- enum target_register_class reg_class) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- +- switch (reg_class) { +- case REG_CLASS_ALL: +- return nds32_get_all_reg_list(nds32, reg_list, reg_list_size); +- case REG_CLASS_GENERAL: +- return nds32_get_general_reg_list(nds32, reg_list, reg_list_size); +- default: +- return ERROR_FAIL; +- } +- +- return ERROR_FAIL; +-} +- +-static int nds32_select_memory_mode(struct target *target, uint32_t address, +- uint32_t length, uint32_t *end_address) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_memory *memory = &(nds32->memory); +- struct nds32_edm *edm = &(nds32->edm); +- uint32_t dlm_start, dlm_end; +- uint32_t ilm_start, ilm_end; +- uint32_t address_end = address + length; +- +- /* init end_address */ +- *end_address = address_end; +- +- if (memory->access_channel == NDS_MEMORY_ACC_CPU) +- return ERROR_OK; +- +- if (edm->access_control == false) { +- LOG_DEBUG("EDM does not support ACC_CTL"); +- return ERROR_OK; +- } +- +- if (edm->direct_access_local_memory == false) { +- LOG_DEBUG("EDM does not support DALM"); +- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); +- return ERROR_OK; +- } +- +- if (memory->mode != NDS_MEMORY_SELECT_AUTO) { +- LOG_DEBUG("Memory mode is not AUTO"); +- return ERROR_OK; +- } +- +- /* set default mode */ +- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); +- +- if ((memory->ilm_base != 0) && (memory->ilm_enable == true)) { +- ilm_start = memory->ilm_start; +- ilm_end = memory->ilm_end; +- +- /* case 1, address < ilm_start */ +- if (address < ilm_start) { +- if (ilm_start < address_end) { +- /* update end_address to split non-ILM from ILM */ +- *end_address = ilm_start; +- } +- /* MEM mode */ +- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); +- } else if ((ilm_start <= address) && (address < ilm_end)) { +- /* case 2, ilm_start <= address < ilm_end */ +- if (ilm_end < address_end) { +- /* update end_address to split non-ILM from ILM */ +- *end_address = ilm_end; +- } +- /* ILM mode */ +- aice_memory_mode(aice, NDS_MEMORY_SELECT_ILM); +- } else { /* case 3, ilm_end <= address */ +- /* MEM mode */ +- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); +- } +- +- return ERROR_OK; +- } else { +- LOG_DEBUG("ILM is not enabled"); +- } +- +- if ((memory->dlm_base != 0) && (memory->dlm_enable == true)) { +- dlm_start = memory->dlm_start; +- dlm_end = memory->dlm_end; +- +- /* case 1, address < dlm_start */ +- if (address < dlm_start) { +- if (dlm_start < address_end) { +- /* update end_address to split non-DLM from DLM */ +- *end_address = dlm_start; +- } +- /* MEM mode */ +- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); +- } else if ((dlm_start <= address) && (address < dlm_end)) { +- /* case 2, dlm_start <= address < dlm_end */ +- if (dlm_end < address_end) { +- /* update end_address to split non-DLM from DLM */ +- *end_address = dlm_end; +- } +- /* DLM mode */ +- aice_memory_mode(aice, NDS_MEMORY_SELECT_DLM); +- } else { /* case 3, dlm_end <= address */ +- /* MEM mode */ +- aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); +- } +- +- return ERROR_OK; +- } else { +- LOG_DEBUG("DLM is not enabled"); +- } +- +- return ERROR_OK; +-} +- +-int nds32_read_buffer(struct target *target, uint32_t address, +- uint32_t size, uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- LOG_DEBUG("READ BUFFER: ADDR %08" PRIx32 " SIZE %08" PRIx32, +- address, +- size); +- +- int retval = ERROR_OK; +- struct aice_port_s *aice = target_to_aice(target); +- uint32_t end_address; +- +- if (((address % 2) == 0) && (size == 2)) { +- nds32_select_memory_mode(target, address, 2, &end_address); +- return aice_read_mem_unit(aice, address, 2, 1, buffer); +- } +- +- /* handle unaligned head bytes */ +- if (address % 4) { +- uint32_t unaligned = 4 - (address % 4); +- +- if (unaligned > size) +- unaligned = size; +- +- nds32_select_memory_mode(target, address, unaligned, &end_address); +- retval = aice_read_mem_unit(aice, address, 1, unaligned, buffer); +- if (retval != ERROR_OK) +- return retval; +- +- buffer += unaligned; +- address += unaligned; +- size -= unaligned; +- } +- +- /* handle aligned words */ +- if (size >= 4) { +- int aligned = size - (size % 4); +- int read_len; +- +- do { +- nds32_select_memory_mode(target, address, aligned, &end_address); +- +- read_len = end_address - address; +- +- if (read_len > 8) +- retval = aice_read_mem_bulk(aice, address, read_len, buffer); +- else +- retval = aice_read_mem_unit(aice, address, 4, read_len / 4, buffer); +- +- if (retval != ERROR_OK) +- return retval; +- +- buffer += read_len; +- address += read_len; +- size -= read_len; +- aligned -= read_len; +- +- } while (aligned != 0); +- } +- +- /*prevent byte access when possible (avoid AHB access limitations in some cases)*/ +- if (size >= 2) { +- int aligned = size - (size % 2); +- nds32_select_memory_mode(target, address, aligned, &end_address); +- retval = aice_read_mem_unit(aice, address, 2, aligned / 2, buffer); +- if (retval != ERROR_OK) +- return retval; +- +- buffer += aligned; +- address += aligned; +- size -= aligned; +- } +- /* handle tail writes of less than 4 bytes */ +- if (size > 0) { +- nds32_select_memory_mode(target, address, size, &end_address); +- retval = aice_read_mem_unit(aice, address, 1, size, buffer); +- if (retval != ERROR_OK) +- return retval; +- } +- +- return ERROR_OK; +-} +- +-int nds32_read_memory(struct target *target, uint32_t address, +- uint32_t size, uint32_t count, uint8_t *buffer) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- +- return aice_read_mem_unit(aice, address, size, count, buffer); +-} +- +-int nds32_read_phys_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, uint8_t *buffer) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- enum nds_memory_access orig_channel; +- int result; +- +- /* switch to BUS access mode to skip MMU */ +- orig_channel = memory->access_channel; +- memory->access_channel = NDS_MEMORY_ACC_BUS; +- aice_memory_access(aice, memory->access_channel); +- +- /* The input address is physical address. No need to do address translation. */ +- result = aice_read_mem_unit(aice, address, size, count, buffer); +- +- /* restore to origin access mode */ +- memory->access_channel = orig_channel; +- aice_memory_access(aice, memory->access_channel); +- +- return result; +-} +- +-int nds32_write_buffer(struct target *target, uint32_t address, +- uint32_t size, const uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- LOG_DEBUG("WRITE BUFFER: ADDR %08" PRIx32 " SIZE %08" PRIx32, +- address, +- size); +- +- struct aice_port_s *aice = target_to_aice(target); +- int retval = ERROR_OK; +- uint32_t end_address; +- +- if (((address % 2) == 0) && (size == 2)) { +- nds32_select_memory_mode(target, address, 2, &end_address); +- return aice_write_mem_unit(aice, address, 2, 1, buffer); +- } +- +- /* handle unaligned head bytes */ +- if (address % 4) { +- uint32_t unaligned = 4 - (address % 4); +- +- if (unaligned > size) +- unaligned = size; +- +- nds32_select_memory_mode(target, address, unaligned, &end_address); +- retval = aice_write_mem_unit(aice, address, 1, unaligned, buffer); +- if (retval != ERROR_OK) +- return retval; +- +- buffer += unaligned; +- address += unaligned; +- size -= unaligned; +- } +- +- /* handle aligned words */ +- if (size >= 4) { +- int aligned = size - (size % 4); +- int write_len; +- +- do { +- nds32_select_memory_mode(target, address, aligned, &end_address); +- +- write_len = end_address - address; +- if (write_len > 8) +- retval = aice_write_mem_bulk(aice, address, write_len, buffer); +- else +- retval = aice_write_mem_unit(aice, address, 4, write_len / 4, buffer); +- if (retval != ERROR_OK) +- return retval; +- +- buffer += write_len; +- address += write_len; +- size -= write_len; +- aligned -= write_len; +- +- } while (aligned != 0); +- } +- +- /* handle tail writes of less than 4 bytes */ +- if (size > 0) { +- nds32_select_memory_mode(target, address, size, &end_address); +- retval = aice_write_mem_unit(aice, address, 1, size, buffer); +- if (retval != ERROR_OK) +- return retval; +- } +- +- return retval; +-} +- +-int nds32_write_memory(struct target *target, uint32_t address, +- uint32_t size, uint32_t count, const uint8_t *buffer) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- +- return aice_write_mem_unit(aice, address, size, count, buffer); +-} +- +-int nds32_write_phys_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, const uint8_t *buffer) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- enum nds_memory_access orig_channel; +- int result; +- +- /* switch to BUS access mode to skip MMU */ +- orig_channel = memory->access_channel; +- memory->access_channel = NDS_MEMORY_ACC_BUS; +- aice_memory_access(aice, memory->access_channel); +- +- /* The input address is physical address. No need to do address translation. */ +- result = aice_write_mem_unit(aice, address, size, count, buffer); +- +- /* restore to origin access mode */ +- memory->access_channel = orig_channel; +- aice_memory_access(aice, memory->access_channel); +- +- return result; +-} +- +-int nds32_mmu(struct target *target, int *enabled) +-{ +- if (target->state != TARGET_HALTED) { +- LOG_ERROR("%s: target not halted", __func__); +- return ERROR_TARGET_INVALID; +- } +- +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); +- +- if ((mmu_config->memory_protection == 2) && (memory->address_translation == true)) +- *enabled = 1; +- else +- *enabled = 0; +- +- return ERROR_OK; +-} +- +-int nds32_arch_state(struct target *target) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (nds32->common_magic != NDS32_COMMON_MAGIC) { +- LOG_ERROR("BUG: called for a non-Andes target"); +- return ERROR_FAIL; +- } +- +- uint32_t value_pc, value_psw; +- +- nds32_get_mapped_reg(nds32, PC, &value_pc); +- nds32_get_mapped_reg(nds32, IR0, &value_psw); +- +- LOG_USER("target halted due to %s\n" +- "psw: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s", +- debug_reason_name(target), +- value_psw, +- value_pc, +- nds32->virtual_hosting ? ", virtual hosting" : ""); +- +- /* save pc value to pseudo register pc */ +- struct reg *reg = register_get_by_name(target->reg_cache, "pc", true); +- buf_set_u32(reg->value, 0, 32, value_pc); +- +- return ERROR_OK; +-} +- +-static void nds32_init_must_have_registers(struct nds32 *nds32) +-{ +- struct reg_cache *reg_cache = nds32->core_cache; +- +- /** MUST have general registers */ +- ((struct nds32_reg *)reg_cache->reg_list[R0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R3].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R4].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R5].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R6].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R7].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R8].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R9].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R10].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R15].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R28].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R29].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R30].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R31].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[PC].arch_info)->enable = true; +- +- /** MUST have configuration system registers */ +- ((struct nds32_reg *)reg_cache->reg_list[CR0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CR1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CR2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CR3].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CR4].arch_info)->enable = true; +- +- /** MUST have interrupt system registers */ +- ((struct nds32_reg *)reg_cache->reg_list[IR0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR3].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR4].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR6].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR9].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR11].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR14].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR15].arch_info)->enable = true; +- +- /** MUST have MMU system registers */ +- ((struct nds32_reg *)reg_cache->reg_list[MR0].arch_info)->enable = true; +- +- /** MUST have EDM system registers */ +- ((struct nds32_reg *)reg_cache->reg_list[DR40].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DR42].arch_info)->enable = true; +-} +- +-static int nds32_init_memory_config(struct nds32 *nds32) +-{ +- uint32_t value_cr1; /* ICM_CFG */ +- uint32_t value_cr2; /* DCM_CFG */ +- struct nds32_memory *memory = &(nds32->memory); +- +- /* read $cr1 to init instruction memory information */ +- nds32_get_mapped_reg(nds32, CR1, &value_cr1); +- memory->icache.set = value_cr1 & 0x7; +- memory->icache.way = (value_cr1 >> 3) & 0x7; +- memory->icache.line_size = (value_cr1 >> 6) & 0x7; +- memory->icache.lock_support = (value_cr1 >> 9) & 0x1; +- +- memory->ilm_base = (value_cr1 >> 10) & 0x7; +- memory->ilm_align_ver = (value_cr1 >> 13) & 0x3; +- +- /* read $cr2 to init data memory information */ +- nds32_get_mapped_reg(nds32, CR2, &value_cr2); +- memory->dcache.set = value_cr2 & 0x7; +- memory->dcache.way = (value_cr2 >> 3) & 0x7; +- memory->dcache.line_size = (value_cr2 >> 6) & 0x7; +- memory->dcache.lock_support = (value_cr2 >> 9) & 0x1; +- +- memory->dlm_base = (value_cr2 >> 10) & 0x7; +- memory->dlm_align_ver = (value_cr2 >> 13) & 0x3; +- +- return ERROR_OK; +-} +- +-static void nds32_init_config(struct nds32 *nds32) +-{ +- uint32_t value_cr0; +- uint32_t value_cr3; +- uint32_t value_cr4; +- struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); +- struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); +- struct nds32_misc_config *misc_config = &(nds32->misc_config); +- +- nds32_get_mapped_reg(nds32, CR0, &value_cr0); +- nds32_get_mapped_reg(nds32, CR3, &value_cr3); +- nds32_get_mapped_reg(nds32, CR4, &value_cr4); +- +- /* config cpu version */ +- cpu_version->performance_extension = value_cr0 & 0x1; +- cpu_version->_16bit_extension = (value_cr0 >> 1) & 0x1; +- cpu_version->performance_extension_2 = (value_cr0 >> 2) & 0x1; +- cpu_version->cop_fpu_extension = (value_cr0 >> 3) & 0x1; +- cpu_version->string_extension = (value_cr0 >> 4) & 0x1; +- cpu_version->revision = (value_cr0 >> 16) & 0xFF; +- cpu_version->cpu_id_family = (value_cr0 >> 24) & 0xF; +- cpu_version->cpu_id_version = (value_cr0 >> 28) & 0xF; +- +- /* config MMU */ +- mmu_config->memory_protection = value_cr3 & 0x3; +- mmu_config->memory_protection_version = (value_cr3 >> 2) & 0x1F; +- mmu_config->fully_associative_tlb = (value_cr3 >> 7) & 0x1; +- if (mmu_config->fully_associative_tlb) { +- mmu_config->tlb_size = (value_cr3 >> 8) & 0x7F; +- } else { +- mmu_config->tlb_ways = (value_cr3 >> 8) & 0x7; +- mmu_config->tlb_sets = (value_cr3 >> 11) & 0x7; +- } +- mmu_config->_8k_page_support = (value_cr3 >> 15) & 0x1; +- mmu_config->extra_page_size_support = (value_cr3 >> 16) & 0xFF; +- mmu_config->tlb_lock = (value_cr3 >> 24) & 0x1; +- mmu_config->hardware_page_table_walker = (value_cr3 >> 25) & 0x1; +- mmu_config->default_endian = (value_cr3 >> 26) & 0x1; +- mmu_config->partition_num = (value_cr3 >> 27) & 0x1; +- mmu_config->invisible_tlb = (value_cr3 >> 28) & 0x1; +- mmu_config->vlpt = (value_cr3 >> 29) & 0x1; +- mmu_config->ntme = (value_cr3 >> 30) & 0x1; +- mmu_config->drde = (value_cr3 >> 31) & 0x1; +- +- /* config misc */ +- misc_config->edm = value_cr4 & 0x1; +- misc_config->local_memory_dma = (value_cr4 >> 1) & 0x1; +- misc_config->performance_monitor = (value_cr4 >> 2) & 0x1; +- misc_config->high_speed_memory_port = (value_cr4 >> 3) & 0x1; +- misc_config->debug_tracer = (value_cr4 >> 4) & 0x1; +- misc_config->div_instruction = (value_cr4 >> 5) & 0x1; +- misc_config->mac_instruction = (value_cr4 >> 6) & 0x1; +- misc_config->audio_isa = (value_cr4 >> 7) & 0x3; +- misc_config->l2_cache = (value_cr4 >> 9) & 0x1; +- misc_config->reduce_register = (value_cr4 >> 10) & 0x1; +- misc_config->addr_24 = (value_cr4 >> 11) & 0x1; +- misc_config->interruption_level = (value_cr4 >> 12) & 0x1; +- misc_config->baseline_instruction = (value_cr4 >> 13) & 0x7; +- misc_config->no_dx_register = (value_cr4 >> 16) & 0x1; +- misc_config->implement_dependant_register = (value_cr4 >> 17) & 0x1; +- misc_config->implement_dependant_sr_encoding = (value_cr4 >> 18) & 0x1; +- misc_config->ifc = (value_cr4 >> 19) & 0x1; +- misc_config->mcu = (value_cr4 >> 20) & 0x1; +- misc_config->shadow = (value_cr4 >> 21) & 0x7; +- misc_config->ex9 = (value_cr4 >> 24) & 0x1; +- +- nds32_init_memory_config(nds32); +-} +- +-static int nds32_init_option_registers(struct nds32 *nds32) +-{ +- struct reg_cache *reg_cache = nds32->core_cache; +- struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); +- struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); +- struct nds32_misc_config *misc_config = &(nds32->misc_config); +- struct nds32_memory *memory_config = &(nds32->memory); +- +- bool no_cr5; +- bool mr10_exist; +- bool no_racr0; +- +- if (((cpu_version->cpu_id_family == 0xC) || (cpu_version->cpu_id_family == 0xD)) && +- ((cpu_version->revision & 0xFC) == 0)) { +- no_cr5 = true; +- mr10_exist = true; +- no_racr0 = true; +- } else { +- no_cr5 = false; +- mr10_exist = false; +- no_racr0 = false; +- } +- +- if (misc_config->reduce_register == false) { +- ((struct nds32_reg *)reg_cache->reg_list[R11].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R12].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R13].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R14].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R16].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R17].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R18].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R19].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R20].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R21].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R22].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R23].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R24].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R25].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R26].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[R27].arch_info)->enable = true; +- } +- +- if (misc_config->no_dx_register == false) { +- ((struct nds32_reg *)reg_cache->reg_list[D0LO].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[D0HI].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[D1LO].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[D1HI].arch_info)->enable = true; +- } +- +- if (misc_config->ex9) +- ((struct nds32_reg *)reg_cache->reg_list[ITB].arch_info)->enable = true; +- +- if (no_cr5 == false) +- ((struct nds32_reg *)reg_cache->reg_list[CR5].arch_info)->enable = true; +- +- if (cpu_version->cop_fpu_extension) { +- ((struct nds32_reg *)reg_cache->reg_list[CR6].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[FPCSR].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[FPCFG].arch_info)->enable = true; +- } +- +- if (mmu_config->memory_protection == 1) { +- /* Secure MPU has no IPC, IPSW, P_ITYPE */ +- ((struct nds32_reg *)reg_cache->reg_list[IR1].arch_info)->enable = false; +- ((struct nds32_reg *)reg_cache->reg_list[IR9].arch_info)->enable = false; +- } +- +- if (nds32->privilege_level != 0) +- ((struct nds32_reg *)reg_cache->reg_list[IR3].arch_info)->enable = false; +- +- if (misc_config->mcu == true) +- ((struct nds32_reg *)reg_cache->reg_list[IR4].arch_info)->enable = false; +- +- if (misc_config->interruption_level == false) { +- ((struct nds32_reg *)reg_cache->reg_list[IR2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR5].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR10].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR12].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR13].arch_info)->enable = true; +- +- /* Secure MPU has no IPC, IPSW, P_ITYPE */ +- if (mmu_config->memory_protection != 1) +- ((struct nds32_reg *)reg_cache->reg_list[IR7].arch_info)->enable = true; +- } +- +- if ((cpu_version->cpu_id_family == 0x9) || +- (cpu_version->cpu_id_family == 0xA) || +- (cpu_version->cpu_id_family == 0xC) || +- (cpu_version->cpu_id_family == 0xD)) +- ((struct nds32_reg *)reg_cache->reg_list[IR8].arch_info)->enable = true; +- +- if (misc_config->shadow == 1) { +- ((struct nds32_reg *)reg_cache->reg_list[IR16].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR17].arch_info)->enable = true; +- } +- +- if (misc_config->ifc) +- ((struct nds32_reg *)reg_cache->reg_list[IFC_LP].arch_info)->enable = true; +- +- if (nds32->privilege_level != 0) +- ((struct nds32_reg *)reg_cache->reg_list[MR0].arch_info)->enable = false; +- +- if (mmu_config->memory_protection == 1) { +- if (mmu_config->memory_protection_version == 24) +- ((struct nds32_reg *)reg_cache->reg_list[MR4].arch_info)->enable = true; +- +- if (nds32->privilege_level == 0) { +- if ((mmu_config->memory_protection_version == 16) || +- (mmu_config->memory_protection_version == 24)) { +- ((struct nds32_reg *)reg_cache->reg_list[MR11].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[SECUR0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR20].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR22].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR24].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR30].arch_info)->enable = true; +- +- if (misc_config->shadow == 1) { +- ((struct nds32_reg *)reg_cache->reg_list[IR21].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR23].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR25].arch_info)->enable = true; +- } +- } +- } +- } else if (mmu_config->memory_protection == 2) { +- ((struct nds32_reg *)reg_cache->reg_list[MR1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[MR4].arch_info)->enable = true; +- +- if ((cpu_version->cpu_id_family != 0xA) && (cpu_version->cpu_id_family != 0xC) && +- (cpu_version->cpu_id_family != 0xD)) +- ((struct nds32_reg *)reg_cache->reg_list[MR5].arch_info)->enable = true; +- } +- +- if (mmu_config->memory_protection > 0) { +- ((struct nds32_reg *)reg_cache->reg_list[MR2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[MR3].arch_info)->enable = true; +- } +- +- if (memory_config->ilm_base != 0) +- if (nds32->privilege_level == 0) +- ((struct nds32_reg *)reg_cache->reg_list[MR6].arch_info)->enable = true; +- +- if (memory_config->dlm_base != 0) +- if (nds32->privilege_level == 0) +- ((struct nds32_reg *)reg_cache->reg_list[MR7].arch_info)->enable = true; +- +- if ((memory_config->icache.line_size != 0) && (memory_config->dcache.line_size != 0)) +- ((struct nds32_reg *)reg_cache->reg_list[MR8].arch_info)->enable = true; +- +- if (misc_config->high_speed_memory_port) +- ((struct nds32_reg *)reg_cache->reg_list[MR9].arch_info)->enable = true; +- +- if (mr10_exist) +- ((struct nds32_reg *)reg_cache->reg_list[MR10].arch_info)->enable = true; +- +- if (misc_config->edm) { +- int dr_reg_n = nds32->edm.breakpoint_num * 5; +- +- for (int i = 0 ; i < dr_reg_n ; i++) +- ((struct nds32_reg *)reg_cache->reg_list[DR0 + i].arch_info)->enable = true; +- +- ((struct nds32_reg *)reg_cache->reg_list[DR41].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DR43].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DR44].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DR45].arch_info)->enable = true; +- } +- +- if (misc_config->debug_tracer) { +- ((struct nds32_reg *)reg_cache->reg_list[DR46].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DR47].arch_info)->enable = true; +- } +- +- if (misc_config->performance_monitor) { +- ((struct nds32_reg *)reg_cache->reg_list[PFR0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[PFR1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[PFR2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[PFR3].arch_info)->enable = true; +- } +- +- if (misc_config->local_memory_dma) { +- ((struct nds32_reg *)reg_cache->reg_list[DMAR0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR3].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR4].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR5].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR6].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR7].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR8].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR9].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[DMAR10].arch_info)->enable = true; +- } +- +- if ((misc_config->local_memory_dma || misc_config->performance_monitor) && +- (no_racr0 == false)) +- ((struct nds32_reg *)reg_cache->reg_list[RACR].arch_info)->enable = true; +- +- if (cpu_version->cop_fpu_extension || (misc_config->audio_isa != 0)) +- ((struct nds32_reg *)reg_cache->reg_list[FUCPR].arch_info)->enable = true; +- +- if (misc_config->audio_isa != 0) { +- if (misc_config->audio_isa > 1) { +- ((struct nds32_reg *)reg_cache->reg_list[D0L24].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[D1L24].arch_info)->enable = true; +- } +- +- ((struct nds32_reg *)reg_cache->reg_list[I0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[I1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[I2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[I3].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[I4].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[I5].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[I6].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[I7].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[M1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[M2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[M3].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[M5].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[M6].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[M7].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[MOD].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[LBE].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[LE].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[LC].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[ADM_VBASE].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[SHFT_CTL0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[SHFT_CTL1].arch_info)->enable = true; +- +- uint32_t value_mod; +- uint32_t fucpr_backup; +- /* enable fpu and get configuration */ +- nds32_get_mapped_reg(nds32, FUCPR, &fucpr_backup); +- if ((fucpr_backup & 0x80000000) == 0) +- nds32_set_mapped_reg(nds32, FUCPR, fucpr_backup | 0x80000000); +- nds32_get_mapped_reg(nds32, MOD, &value_mod); +- /* restore origin fucpr value */ +- if ((fucpr_backup & 0x80000000) == 0) +- nds32_set_mapped_reg(nds32, FUCPR, fucpr_backup); +- +- if ((value_mod >> 6) & 0x1) { +- ((struct nds32_reg *)reg_cache->reg_list[CB_CTL].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CBB0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CBB1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CBB2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CBB3].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CBE0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CBE1].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CBE2].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[CBE3].arch_info)->enable = true; +- } +- } +- +- if ((cpu_version->cpu_id_family == 0x9) || +- (cpu_version->cpu_id_family == 0xA) || +- (cpu_version->cpu_id_family == 0xC)) { +- +- ((struct nds32_reg *)reg_cache->reg_list[IDR0].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IDR1].arch_info)->enable = true; +- +- if ((cpu_version->cpu_id_family == 0xC) && (cpu_version->revision == 0x0C)) +- ((struct nds32_reg *)reg_cache->reg_list[IDR0].arch_info)->enable = false; +- } +- +- uint32_t ir3_value; +- uint32_t ivb_prog_pri_lvl; +- uint32_t ivb_ivic_ver; +- +- nds32_get_mapped_reg(nds32, IR3, &ir3_value); +- ivb_prog_pri_lvl = ir3_value & 0x1; +- ivb_ivic_ver = (ir3_value >> 11) & 0x3; +- +- if ((ivb_prog_pri_lvl == 1) || (ivb_ivic_ver >= 1)) { +- ((struct nds32_reg *)reg_cache->reg_list[IR18].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR19].arch_info)->enable = true; +- } +- +- if (ivb_ivic_ver >= 1) { +- ((struct nds32_reg *)reg_cache->reg_list[IR26].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR27].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR28].arch_info)->enable = true; +- ((struct nds32_reg *)reg_cache->reg_list[IR29].arch_info)->enable = true; +- } +- +- return ERROR_OK; +-} +- +-int nds32_init_register_table(struct nds32 *nds32) +-{ +- nds32_init_must_have_registers(nds32); +- +- return ERROR_OK; +-} +- +-int nds32_add_software_breakpoint(struct target *target, +- struct breakpoint *breakpoint) +-{ +- uint32_t data; +- uint32_t check_data; +- uint32_t break_insn; +- +- /* check the breakpoint size */ +- target->type->read_buffer(target, breakpoint->address, 4, (uint8_t *)&data); +- +- /* backup origin instruction +- * instruction is big-endian */ +- if (*(char *)&data & 0x80) { /* 16-bits instruction */ +- breakpoint->length = 2; +- break_insn = NDS32_BREAK_16; +- } else { /* 32-bits instruction */ +- breakpoint->length = 4; +- break_insn = NDS32_BREAK_32; +- } +- +- free(breakpoint->orig_instr); +- +- breakpoint->orig_instr = malloc(breakpoint->length); +- memcpy(breakpoint->orig_instr, &data, breakpoint->length); +- +- /* self-modified code */ +- target->type->write_buffer(target, breakpoint->address, breakpoint->length, (const uint8_t *)&break_insn); +- /* write_back & invalidate dcache & invalidate icache */ +- nds32_cache_sync(target, breakpoint->address, breakpoint->length); +- +- /* read back to check */ +- target->type->read_buffer(target, breakpoint->address, breakpoint->length, (uint8_t *)&check_data); +- if (memcmp(&check_data, &break_insn, breakpoint->length) == 0) +- return ERROR_OK; +- +- return ERROR_FAIL; +-} +- +-int nds32_remove_software_breakpoint(struct target *target, +- struct breakpoint *breakpoint) +-{ +- uint32_t check_data; +- uint32_t break_insn; +- +- if (breakpoint->length == 2) +- break_insn = NDS32_BREAK_16; +- else if (breakpoint->length == 4) +- break_insn = NDS32_BREAK_32; +- else +- return ERROR_FAIL; +- +- target->type->read_buffer(target, breakpoint->address, breakpoint->length, +- (uint8_t *)&check_data); +- +- /* break instruction is modified */ +- if (memcmp(&check_data, &break_insn, breakpoint->length) != 0) +- return ERROR_FAIL; +- +- /* self-modified code */ +- target->type->write_buffer(target, breakpoint->address, breakpoint->length, +- breakpoint->orig_instr); +- +- /* write_back & invalidate dcache & invalidate icache */ +- nds32_cache_sync(target, breakpoint->address, breakpoint->length); +- +- return ERROR_OK; +-} +- +-/** +- * Restore the processor context on an Andes target. The full processor +- * context is analyzed to see if any of the registers are dirty on this end, but +- * have a valid new value. If this is the case, the processor is changed to the +- * appropriate mode and the new register values are written out to the +- * processor. If there happens to be a dirty register with an invalid value, an +- * error will be logged. +- * +- * @param target Pointer to the Andes target to have its context restored +- * @return Error status if the target is not halted. +- */ +-int nds32_restore_context(struct target *target) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct reg_cache *reg_cache = nds32->core_cache; +- struct reg *reg; +- struct nds32_reg *reg_arch_info; +- unsigned int i; +- +- LOG_DEBUG("-"); +- +- if (target->state != TARGET_HALTED) { +- LOG_WARNING("target not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- /* check if there are dirty registers */ +- for (i = 0; i < reg_cache->num_regs; i++) { +- reg = &(reg_cache->reg_list[i]); +- if (reg->dirty == true) { +- if (reg->valid == true) { +- +- LOG_DEBUG("examining dirty reg: %s", reg->name); +- LOG_DEBUG("writing register %d with value 0x%8.8" PRIx32, +- i, buf_get_u32(reg->value, 0, 32)); +- +- reg_arch_info = reg->arch_info; +- if (reg_arch_info->num >= FD0 && reg_arch_info->num <= FD31) { +- uint64_t val = buf_get_u64(reg_arch_info->value, 0, 64); +- aice_write_reg_64(aice, reg_arch_info->num, val); +- } else { +- uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); +- aice_write_register(aice, reg_arch_info->num, val); +- } +- +- reg->valid = true; +- reg->dirty = false; +- } +- } +- } +- +- return ERROR_OK; +-} +- +-int nds32_edm_config(struct nds32 *nds32) +-{ +- struct target *target = nds32->target; +- struct aice_port_s *aice = target_to_aice(target); +- uint32_t edm_cfg; +- uint32_t edm_ctl; +- +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); +- +- nds32->edm.version = (edm_cfg >> 16) & 0xFFFF; +- LOG_INFO("EDM version 0x%04x", nds32->edm.version); +- +- nds32->edm.breakpoint_num = (edm_cfg & 0x7) + 1; +- +- if ((nds32->edm.version & 0x1000) || (nds32->edm.version >= 0x60)) +- nds32->edm.access_control = true; +- else +- nds32->edm.access_control = false; +- +- if ((edm_cfg >> 4) & 0x1) +- nds32->edm.direct_access_local_memory = true; +- else +- nds32->edm.direct_access_local_memory = false; +- +- if (nds32->edm.version <= 0x20) +- nds32->edm.direct_access_local_memory = false; +- +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); +- if (edm_ctl & (0x1 << 29)) +- nds32->edm.support_max_stop = true; +- else +- nds32->edm.support_max_stop = false; +- +- /* set passcode for secure MCU */ +- nds32_login(nds32); +- +- return ERROR_OK; +-} +- +-int nds32_config(struct nds32 *nds32) +-{ +- nds32_init_config(nds32); +- +- /* init optional system registers according to config registers */ +- nds32_init_option_registers(nds32); +- +- /* get max interrupt level */ +- if (nds32->misc_config.interruption_level) +- nds32->max_interrupt_level = 2; +- else +- nds32->max_interrupt_level = 3; +- +- /* get ILM/DLM size from MR6/MR7 */ +- uint32_t value_mr6, value_mr7; +- uint32_t size_index; +- nds32_get_mapped_reg(nds32, MR6, &value_mr6); +- size_index = (value_mr6 >> 1) & 0xF; +- nds32->memory.ilm_size = nds32_lm_size_table[size_index]; +- +- nds32_get_mapped_reg(nds32, MR7, &value_mr7); +- size_index = (value_mr7 >> 1) & 0xF; +- nds32->memory.dlm_size = nds32_lm_size_table[size_index]; +- +- return ERROR_OK; +-} +- +-int nds32_init_arch_info(struct target *target, struct nds32 *nds32) +-{ +- target->arch_info = nds32; +- nds32->target = target; +- +- nds32->common_magic = NDS32_COMMON_MAGIC; +- nds32->init_arch_info_after_halted = false; +- nds32->auto_convert_hw_bp = true; +- nds32->global_stop = false; +- nds32->soft_reset_halt = false; +- nds32->edm_passcode = NULL; +- nds32->privilege_level = 0; +- nds32->boot_time = 1500; +- nds32->reset_halt_as_examine = false; +- nds32->keep_target_edm_ctl = false; +- nds32->word_access_mem = false; +- nds32->virtual_hosting = true; +- nds32->hit_syscall = false; +- nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED; +- nds32->virtual_hosting_errno = 0; +- nds32->virtual_hosting_ctrl_c = false; +- nds32->attached = false; +- +- nds32->syscall_break.asid = 0; +- nds32->syscall_break.length = 4; +- nds32->syscall_break.is_set = false; +- nds32->syscall_break.orig_instr = NULL; +- nds32->syscall_break.next = NULL; +- nds32->syscall_break.unique_id = 0x515CAll + target->target_number; +- nds32->syscall_break.linked_brp = 0; +- +- nds32_reg_init(); +- +- if (nds32_reg_cache_init(target, nds32) == ERROR_FAIL) +- return ERROR_FAIL; +- +- if (nds32_init_register_table(nds32) != ERROR_OK) +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-int nds32_virtual_to_physical(struct target *target, target_addr_t address, target_addr_t *physical) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (nds32->memory.address_translation == false) { +- *physical = address; +- return ERROR_OK; +- } +- +- if (nds32_probe_tlb(nds32, address, physical) == ERROR_OK) +- return ERROR_OK; +- +- if (nds32_walk_page_table(nds32, address, physical) == ERROR_OK) +- return ERROR_OK; +- +- return ERROR_FAIL; +-} +- +-int nds32_cache_sync(struct target *target, target_addr_t address, uint32_t length) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_cache *dcache = &(nds32->memory.dcache); +- struct nds32_cache *icache = &(nds32->memory.icache); +- uint32_t dcache_line_size = nds32_line_size_table[dcache->line_size]; +- uint32_t icache_line_size = nds32_line_size_table[icache->line_size]; +- uint32_t cur_address; +- int result; +- uint32_t start_line, end_line; +- uint32_t cur_line; +- +- if ((dcache->line_size != 0) && (dcache->enable == true)) { +- /* address / dcache_line_size */ +- start_line = address >> (dcache->line_size + 2); +- /* (address + length - 1) / dcache_line_size */ +- end_line = (address + length - 1) >> (dcache->line_size + 2); +- +- for (cur_address = address, cur_line = start_line; +- cur_line <= end_line; +- cur_address += dcache_line_size, cur_line++) { +- /* D$ write back */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_VA_WB, cur_address); +- if (result != ERROR_OK) +- return result; +- +- /* D$ invalidate */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_VA_INVAL, cur_address); +- if (result != ERROR_OK) +- return result; +- } +- } +- +- if ((icache->line_size != 0) && (icache->enable == true)) { +- /* address / icache_line_size */ +- start_line = address >> (icache->line_size + 2); +- /* (address + length - 1) / icache_line_size */ +- end_line = (address + length - 1) >> (icache->line_size + 2); +- +- for (cur_address = address, cur_line = start_line; +- cur_line <= end_line; +- cur_address += icache_line_size, cur_line++) { +- /* Because PSW.IT is turned off under debug exception, address MUST +- * be physical address. L1I_VA_INVALIDATE uses PSW.IT to decide +- * address translation or not. */ +- target_addr_t physical_addr; +- if (target->type->virt2phys(target, cur_address, &physical_addr) == ERROR_FAIL) +- return ERROR_FAIL; +- +- /* I$ invalidate */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_VA_INVAL, physical_addr); +- if (result != ERROR_OK) +- return result; +- } +- } +- +- return ERROR_OK; +-} +- +-uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address) +-{ +- if (!current) +- nds32_set_mapped_reg(nds32, PC, address); +- else +- nds32_get_mapped_reg(nds32, PC, &address); +- +- return address; +-} +- +-int nds32_step(struct target *target, int current, +- target_addr_t address, int handle_breakpoints) +-{ +- LOG_DEBUG("target->state: %s", +- target_state_name(target)); +- +- if (target->state != TARGET_HALTED) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- struct nds32 *nds32 = target_to_nds32(target); +- +- address = nds32_nextpc(nds32, current, address); +- +- LOG_DEBUG("STEP PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : ""); +- +- /** set DSSIM */ +- uint32_t ir14_value; +- nds32_get_mapped_reg(nds32, IR14, &ir14_value); +- if (nds32->step_isr_enable) +- ir14_value |= (0x1 << 31); +- else +- ir14_value &= ~(0x1 << 31); +- nds32_set_mapped_reg(nds32, IR14, ir14_value); +- +- /* check hit_syscall before leave_debug_state() because +- * leave_debug_state() may clear hit_syscall flag */ +- bool no_step = false; +- if (nds32->hit_syscall) +- /* step after hit_syscall should be ignored because +- * leave_debug_state will step implicitly to skip the +- * syscall */ +- no_step = true; +- +- /********* TODO: maybe create another function to handle this part */ +- CHECK_RETVAL(nds32->leave_debug_state(nds32, true)); +- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); +- +- if (no_step == false) { +- struct aice_port_s *aice = target_to_aice(target); +- if (aice_step(aice) != ERROR_OK) +- return ERROR_FAIL; +- } +- +- /* save state */ +- CHECK_RETVAL(nds32->enter_debug_state(nds32, true)); +- /********* TODO: maybe create another function to handle this part */ +- +- /* restore DSSIM */ +- if (nds32->step_isr_enable) { +- nds32_get_mapped_reg(nds32, IR14, &ir14_value); +- ir14_value &= ~(0x1 << 31); +- nds32_set_mapped_reg(nds32, IR14, ir14_value); +- } +- +- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); +- +- return ERROR_OK; +-} +- +-static int nds32_step_without_watchpoint(struct nds32 *nds32) +-{ +- struct target *target = nds32->target; +- +- if (target->state != TARGET_HALTED) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- /** set DSSIM */ +- uint32_t ir14_value; +- nds32_get_mapped_reg(nds32, IR14, &ir14_value); +- if (nds32->step_isr_enable) +- ir14_value |= (0x1 << 31); +- else +- ir14_value &= ~(0x1 << 31); +- nds32_set_mapped_reg(nds32, IR14, ir14_value); +- +- /********* TODO: maybe create another function to handle this part */ +- CHECK_RETVAL(nds32->leave_debug_state(nds32, false)); +- +- struct aice_port_s *aice = target_to_aice(target); +- +- if (aice_step(aice) != ERROR_OK) +- return ERROR_FAIL; +- +- /* save state */ +- CHECK_RETVAL(nds32->enter_debug_state(nds32, false)); +- /********* TODO: maybe create another function to handle this part */ +- +- /* restore DSSIM */ +- if (nds32->step_isr_enable) { +- nds32_get_mapped_reg(nds32, IR14, &ir14_value); +- ir14_value &= ~(0x1 << 31); +- nds32_set_mapped_reg(nds32, IR14, ir14_value); +- } +- +- return ERROR_OK; +-} +- +-int nds32_target_state(struct nds32 *nds32, enum target_state *state) +-{ +- struct aice_port_s *aice = target_to_aice(nds32->target); +- enum aice_target_state_s nds32_state; +- +- if (aice_state(aice, &nds32_state) != ERROR_OK) +- return ERROR_FAIL; +- +- switch (nds32_state) { +- case AICE_DISCONNECT: +- LOG_INFO("USB is disconnected"); +- return ERROR_FAIL; +- case AICE_TARGET_DETACH: +- LOG_INFO("Target is disconnected"); +- return ERROR_FAIL; +- case AICE_TARGET_UNKNOWN: +- *state = TARGET_UNKNOWN; +- break; +- case AICE_TARGET_RUNNING: +- *state = TARGET_RUNNING; +- break; +- case AICE_TARGET_HALTED: +- *state = TARGET_HALTED; +- break; +- case AICE_TARGET_RESET: +- *state = TARGET_RESET; +- break; +- case AICE_TARGET_DEBUG_RUNNING: +- *state = TARGET_DEBUG_RUNNING; +- break; +- default: +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-int nds32_examine_debug_reason(struct nds32 *nds32) +-{ +- uint32_t reason; +- struct target *target = nds32->target; +- +- if (nds32->hit_syscall == true) { +- LOG_DEBUG("Hit syscall breakpoint"); +- target->debug_reason = DBG_REASON_BREAKPOINT; +- return ERROR_OK; +- } +- +- nds32->get_debug_reason(nds32, &reason); +- +- LOG_DEBUG("nds32 examines debug reason: %s", nds32_debug_type_name[reason]); +- +- /* Examine debug reason */ +- switch (reason) { +- case NDS32_DEBUG_BREAK: +- case NDS32_DEBUG_BREAK_16: +- case NDS32_DEBUG_INST_BREAK: +- { +- uint32_t value_pc; +- uint32_t opcode; +- struct nds32_instruction instruction; +- +- nds32_get_mapped_reg(nds32, PC, &value_pc); +- +- if (nds32_read_opcode(nds32, value_pc, &opcode) != ERROR_OK) +- return ERROR_FAIL; +- if (nds32_evaluate_opcode(nds32, opcode, value_pc, &instruction) != ERROR_OK) +- return ERROR_FAIL; +- +- /* hit 'break 0x7FFF' */ +- if ((instruction.info.opc_6 == 0x32) && +- (instruction.info.sub_opc == 0xA) && +- (instruction.info.imm == 0x7FFF)) { +- target->debug_reason = DBG_REASON_EXIT; +- } else +- target->debug_reason = DBG_REASON_BREAKPOINT; +- } +- break; +- case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE: +- case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE: +- case NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP: /* GLOBAL_STOP is precise exception */ +- { +- int result; +- +- result = nds32->get_watched_address(nds32, +- &(nds32->watched_address), reason); +- /* do single step(without watchpoints) to skip the "watched" instruction */ +- nds32_step_without_watchpoint(nds32); +- +- /* before single_step, save exception address */ +- if (result != ERROR_OK) +- return ERROR_FAIL; +- +- target->debug_reason = DBG_REASON_WATCHPOINT; +- } +- break; +- case NDS32_DEBUG_DEBUG_INTERRUPT: +- target->debug_reason = DBG_REASON_DBGRQ; +- break; +- case NDS32_DEBUG_HARDWARE_SINGLE_STEP: +- target->debug_reason = DBG_REASON_SINGLESTEP; +- break; +- case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE: +- case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE: +- case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE: +- if (nds32->get_watched_address(nds32, &(nds32->watched_address), reason) != ERROR_OK) +- return ERROR_FAIL; +- +- target->debug_reason = DBG_REASON_WATCHPOINT; +- break; +- default: +- target->debug_reason = DBG_REASON_UNDEFINED; +- break; +- } +- +- return ERROR_OK; +-} +- +-int nds32_login(struct nds32 *nds32) +-{ +- struct target *target = nds32->target; +- struct aice_port_s *aice = target_to_aice(target); +- uint32_t passcode_length; +- char command_sequence[129]; +- char command_str[33]; +- char code_str[9]; +- uint32_t copy_length; +- uint32_t code; +- uint32_t i; +- +- LOG_DEBUG("nds32_login"); +- +- if (nds32->edm_passcode) { +- /* convert EDM passcode to command sequences */ +- passcode_length = strlen(nds32->edm_passcode); +- command_sequence[0] = '\0'; +- for (i = 0; i < passcode_length; i += 8) { +- if (passcode_length - i < 8) +- copy_length = passcode_length - i; +- else +- copy_length = 8; +- +- strncpy(code_str, nds32->edm_passcode + i, copy_length); +- code_str[copy_length] = '\0'; +- code = strtoul(code_str, NULL, 16); +- +- sprintf(command_str, "write_misc gen_port0 0x%" PRIx32 ";", code); +- strcat(command_sequence, command_str); +- } +- +- if (aice_program_edm(aice, command_sequence) != ERROR_OK) +- return ERROR_FAIL; +- +- /* get current privilege level */ +- uint32_t value_edmsw; +- aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &value_edmsw); +- nds32->privilege_level = (value_edmsw >> 16) & 0x3; +- LOG_INFO("Current privilege level: %d", nds32->privilege_level); +- } +- +- if (nds32_edm_ops_num > 0) { +- const char *reg_name; +- for (i = 0 ; i < nds32_edm_ops_num ; i++) { +- code = nds32_edm_ops[i].value; +- if (nds32_edm_ops[i].reg_no == 6) +- reg_name = "gen_port0"; +- else if (nds32_edm_ops[i].reg_no == 7) +- reg_name = "gen_port1"; +- else +- return ERROR_FAIL; +- +- sprintf(command_str, "write_misc %s 0x%" PRIx32 ";", reg_name, code); +- if (aice_program_edm(aice, command_str) != ERROR_OK) +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-int nds32_halt(struct target *target) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- enum target_state state; +- +- LOG_DEBUG("target->state: %s", +- target_state_name(target)); +- +- if (target->state == TARGET_HALTED) { +- LOG_DEBUG("target was already halted"); +- return ERROR_OK; +- } +- +- if (nds32_target_state(nds32, &state) != ERROR_OK) +- return ERROR_FAIL; +- +- if (state != TARGET_HALTED) +- /* TODO: if state == TARGET_HALTED, check ETYPE is DBGI or not */ +- if (aice_halt(aice) != ERROR_OK) +- return ERROR_FAIL; +- +- CHECK_RETVAL(nds32->enter_debug_state(nds32, true)); +- +- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); +- +- return ERROR_OK; +-} +- +-/* poll current target status */ +-int nds32_poll(struct target *target) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- enum target_state state; +- +- if (nds32_target_state(nds32, &state) != ERROR_OK) +- return ERROR_FAIL; +- +- if (state == TARGET_HALTED) { +- if (target->state != TARGET_HALTED) { +- /* if false_hit, continue free_run */ +- if (nds32->enter_debug_state(nds32, true) != ERROR_OK) { +- struct aice_port_s *aice = target_to_aice(target); +- aice_run(aice); +- return ERROR_OK; +- } +- +- LOG_DEBUG("Change target state to TARGET_HALTED."); +- +- target_call_event_callbacks(target, TARGET_EVENT_HALTED); +- } +- } else if (state == TARGET_RESET) { +- if (target->state == TARGET_HALTED) { +- /* similar to assert srst */ +- register_cache_invalidate(nds32->core_cache); +- target->state = TARGET_RESET; +- +- /* TODO: deassert srst */ +- } else if (target->state == TARGET_RUNNING) { +- /* reset as running */ +- LOG_WARNING("<-- TARGET WARNING! The debug target has been reset. -->"); +- } +- } else { +- if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) { +- LOG_DEBUG("Change target state to TARGET_RUNNING."); +- target->state = TARGET_RUNNING; +- target->debug_reason = DBG_REASON_NOTHALTED; +- } +- } +- +- return ERROR_OK; +-} +- +-int nds32_resume(struct target *target, int current, +- target_addr_t address, int handle_breakpoints, int debug_execution) +-{ +- LOG_DEBUG("current %d address %08" TARGET_PRIxADDR +- " handle_breakpoints %d" +- " debug_execution %d", +- current, address, handle_breakpoints, debug_execution); +- +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (target->state != TARGET_HALTED) { +- LOG_ERROR("Target not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- address = nds32_nextpc(nds32, current, address); +- +- LOG_DEBUG("RESUME PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : ""); +- +- if (!debug_execution) +- target_free_all_working_areas(target); +- +- /* Disable HSS to avoid users misuse HSS */ +- if (nds32_reach_max_interrupt_level(nds32) == false) { +- uint32_t value_ir0; +- nds32_get_mapped_reg(nds32, IR0, &value_ir0); +- value_ir0 &= ~(0x1 << 11); +- nds32_set_mapped_reg(nds32, IR0, value_ir0); +- } +- +- CHECK_RETVAL(nds32->leave_debug_state(nds32, true)); +- CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); +- +- if (nds32->virtual_hosting_ctrl_c == false) { +- struct aice_port_s *aice = target_to_aice(target); +- aice_run(aice); +- } else +- nds32->virtual_hosting_ctrl_c = false; +- +- target->debug_reason = DBG_REASON_NOTHALTED; +- if (!debug_execution) +- target->state = TARGET_RUNNING; +- else +- target->state = TARGET_DEBUG_RUNNING; +- +- LOG_DEBUG("target->state: %s", +- target_state_name(target)); +- +- return ERROR_OK; +-} +- +-static int nds32_soft_reset_halt(struct target *target) +-{ +- /* TODO: test it */ +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- +- aice_assert_srst(aice, AICE_SRST); +- +- /* halt core and set pc to 0x0 */ +- int retval = target_halt(target); +- if (retval != ERROR_OK) +- return retval; +- +- /* start fetching from IVB */ +- uint32_t value_ir3; +- nds32_get_mapped_reg(nds32, IR3, &value_ir3); +- nds32_set_mapped_reg(nds32, PC, value_ir3 & 0xFFFF0000); +- +- return ERROR_OK; +-} +- +-int nds32_assert_reset(struct target *target) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); +- +- /* TODO: apply hw reset signal in not examined state */ +- if (!(target_was_examined(target))) { +- LOG_WARNING("Reset is not asserted because the target is not examined."); +- LOG_WARNING("Use a reset button or power cycle the target."); +- return ERROR_TARGET_NOT_EXAMINED; +- } +- +- if (target->reset_halt) { +- if ((nds32->soft_reset_halt) +- || (nds32->edm.version < 0x51) +- || ((nds32->edm.version == 0x51) +- && (cpu_version->revision == 0x1C) +- && (cpu_version->cpu_id_family == 0xC) +- && (cpu_version->cpu_id_version == 0x0))) +- nds32_soft_reset_halt(target); +- else +- aice_assert_srst(aice, AICE_RESET_HOLD); +- } else { +- aice_assert_srst(aice, AICE_SRST); +- alive_sleep(nds32->boot_time); +- } +- +- /* set passcode for secure MCU after core reset */ +- nds32_login(nds32); +- +- /* registers are now invalid */ +- register_cache_invalidate(nds32->core_cache); +- +- target->state = TARGET_RESET; +- +- return ERROR_OK; +-} +- +-static int nds32_gdb_attach(struct nds32 *nds32) +-{ +- LOG_DEBUG("nds32_gdb_attach, target coreid: %" PRId32, nds32->target->coreid); +- +- if (nds32->attached == false) { +- +- if (nds32->keep_target_edm_ctl) { +- /* backup target EDM_CTL */ +- struct aice_port_s *aice = target_to_aice(nds32->target); +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &nds32->backup_edm_ctl); +- } +- +- target_halt(nds32->target); +- +- nds32->attached = true; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_gdb_detach(struct nds32 *nds32) +-{ +- LOG_DEBUG("nds32_gdb_detach"); +- bool backup_virtual_hosting_setting; +- +- if (nds32->attached) { +- +- backup_virtual_hosting_setting = nds32->virtual_hosting; +- /* turn off virtual hosting before resume as gdb-detach */ +- nds32->virtual_hosting = false; +- target_resume(nds32->target, 1, 0, 0, 0); +- nds32->virtual_hosting = backup_virtual_hosting_setting; +- +- if (nds32->keep_target_edm_ctl) { +- /* restore target EDM_CTL */ +- struct aice_port_s *aice = target_to_aice(nds32->target); +- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, nds32->backup_edm_ctl); +- } +- +- nds32->attached = false; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_callback_event_handler(struct target *target, +- enum target_event event, void *priv) +-{ +- int retval = ERROR_OK; +- int target_number = *(int *)priv; +- +- if (target_number != target->target_number) +- return ERROR_OK; +- +- struct nds32 *nds32 = target_to_nds32(target); +- +- switch (event) { +- case TARGET_EVENT_GDB_ATTACH: +- retval = nds32_gdb_attach(nds32); +- break; +- case TARGET_EVENT_GDB_DETACH: +- retval = nds32_gdb_detach(nds32); +- break; +- default: +- break; +- } +- +- return retval; +-} +- +-int nds32_init(struct nds32 *nds32) +-{ +- /* Initialize anything we can set up without talking to the target */ +- nds32->memory.access_channel = NDS_MEMORY_ACC_CPU; +- +- /* register event callback */ +- target_register_event_callback(nds32_callback_event_handler, +- &(nds32->target->target_number)); +- +- return ERROR_OK; +-} +- +-int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info) +-{ +- /* fill syscall parameters to file-I/O info */ +- if (!fileio_info) { +- LOG_ERROR("Target has not initial file-I/O data structure"); +- return ERROR_FAIL; +- } +- +- struct nds32 *nds32 = target_to_nds32(target); +- uint32_t value_ir6; +- uint32_t syscall_id; +- +- if (nds32->hit_syscall == false) +- return ERROR_FAIL; +- +- nds32_get_mapped_reg(nds32, IR6, &value_ir6); +- syscall_id = (value_ir6 >> 16) & 0x7FFF; +- nds32->active_syscall_id = syscall_id; +- +- LOG_DEBUG("hit syscall ID: 0x%" PRIx32, syscall_id); +- +- /* free previous identifier storage */ +- free(fileio_info->identifier); +- fileio_info->identifier = NULL; +- +- uint32_t reg_r0, reg_r1, reg_r2; +- nds32_get_mapped_reg(nds32, R0, ®_r0); +- nds32_get_mapped_reg(nds32, R1, ®_r1); +- nds32_get_mapped_reg(nds32, R2, ®_r2); +- +- switch (syscall_id) { +- case NDS32_SYSCALL_EXIT: +- fileio_info->identifier = malloc(5); +- sprintf(fileio_info->identifier, "exit"); +- fileio_info->param_1 = reg_r0; +- break; +- case NDS32_SYSCALL_OPEN: +- { +- uint8_t filename[256]; +- fileio_info->identifier = malloc(5); +- sprintf(fileio_info->identifier, "open"); +- fileio_info->param_1 = reg_r0; +- /* reserve fileio_info->param_2 for length of path */ +- fileio_info->param_3 = reg_r1; +- fileio_info->param_4 = reg_r2; +- +- target->type->read_buffer(target, reg_r0, 256, filename); +- fileio_info->param_2 = strlen((char *)filename); +- } +- break; +- case NDS32_SYSCALL_CLOSE: +- fileio_info->identifier = malloc(6); +- sprintf(fileio_info->identifier, "close"); +- fileio_info->param_1 = reg_r0; +- break; +- case NDS32_SYSCALL_READ: +- fileio_info->identifier = malloc(5); +- sprintf(fileio_info->identifier, "read"); +- fileio_info->param_1 = reg_r0; +- fileio_info->param_2 = reg_r1; +- fileio_info->param_3 = reg_r2; +- break; +- case NDS32_SYSCALL_WRITE: +- fileio_info->identifier = malloc(6); +- sprintf(fileio_info->identifier, "write"); +- fileio_info->param_1 = reg_r0; +- fileio_info->param_2 = reg_r1; +- fileio_info->param_3 = reg_r2; +- break; +- case NDS32_SYSCALL_LSEEK: +- fileio_info->identifier = malloc(6); +- sprintf(fileio_info->identifier, "lseek"); +- fileio_info->param_1 = reg_r0; +- fileio_info->param_2 = reg_r1; +- fileio_info->param_3 = reg_r2; +- break; +- case NDS32_SYSCALL_UNLINK: +- { +- uint8_t filename[256]; +- fileio_info->identifier = malloc(7); +- sprintf(fileio_info->identifier, "unlink"); +- fileio_info->param_1 = reg_r0; +- /* reserve fileio_info->param_2 for length of path */ +- +- target->type->read_buffer(target, reg_r0, 256, filename); +- fileio_info->param_2 = strlen((char *)filename); +- } +- break; +- case NDS32_SYSCALL_RENAME: +- { +- uint8_t filename[256]; +- fileio_info->identifier = malloc(7); +- sprintf(fileio_info->identifier, "rename"); +- fileio_info->param_1 = reg_r0; +- /* reserve fileio_info->param_2 for length of old path */ +- fileio_info->param_3 = reg_r1; +- /* reserve fileio_info->param_4 for length of new path */ +- +- target->type->read_buffer(target, reg_r0, 256, filename); +- fileio_info->param_2 = strlen((char *)filename); +- +- target->type->read_buffer(target, reg_r1, 256, filename); +- fileio_info->param_4 = strlen((char *)filename); +- } +- break; +- case NDS32_SYSCALL_FSTAT: +- fileio_info->identifier = malloc(6); +- sprintf(fileio_info->identifier, "fstat"); +- fileio_info->param_1 = reg_r0; +- fileio_info->param_2 = reg_r1; +- break; +- case NDS32_SYSCALL_STAT: +- { +- uint8_t filename[256]; +- fileio_info->identifier = malloc(5); +- sprintf(fileio_info->identifier, "stat"); +- fileio_info->param_1 = reg_r0; +- /* reserve fileio_info->param_2 for length of old path */ +- fileio_info->param_3 = reg_r1; +- +- target->type->read_buffer(target, reg_r0, 256, filename); +- fileio_info->param_2 = strlen((char *)filename) + 1; +- } +- break; +- case NDS32_SYSCALL_GETTIMEOFDAY: +- fileio_info->identifier = malloc(13); +- sprintf(fileio_info->identifier, "gettimeofday"); +- fileio_info->param_1 = reg_r0; +- fileio_info->param_2 = reg_r1; +- break; +- case NDS32_SYSCALL_ISATTY: +- fileio_info->identifier = malloc(7); +- sprintf(fileio_info->identifier, "isatty"); +- fileio_info->param_1 = reg_r0; +- break; +- case NDS32_SYSCALL_SYSTEM: +- { +- uint8_t command[256]; +- fileio_info->identifier = malloc(7); +- sprintf(fileio_info->identifier, "system"); +- fileio_info->param_1 = reg_r0; +- /* reserve fileio_info->param_2 for length of old path */ +- +- target->type->read_buffer(target, reg_r0, 256, command); +- fileio_info->param_2 = strlen((char *)command); +- } +- break; +- case NDS32_SYSCALL_ERRNO: +- fileio_info->identifier = malloc(6); +- sprintf(fileio_info->identifier, "errno"); +- nds32_set_mapped_reg(nds32, R0, nds32->virtual_hosting_errno); +- break; +- default: +- fileio_info->identifier = malloc(8); +- sprintf(fileio_info->identifier, "unknown"); +- break; +- } +- +- return ERROR_OK; +-} +- +-int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c) +-{ +- LOG_DEBUG("syscall return code: 0x%x, errno: 0x%x , ctrl_c: %s", +- retcode, fileio_errno, ctrl_c ? "true" : "false"); +- +- struct nds32 *nds32 = target_to_nds32(target); +- +- nds32_set_mapped_reg(nds32, R0, (uint32_t)retcode); +- +- nds32->virtual_hosting_errno = fileio_errno; +- nds32->virtual_hosting_ctrl_c = ctrl_c; +- nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED; +- +- return ERROR_OK; +-} +- +-int nds32_profiling(struct target *target, uint32_t *samples, +- uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) +-{ +- /* sample $PC every 10 milliseconds */ +- uint32_t iteration = seconds * 100; +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32 *nds32 = target_to_nds32(target); +- +- /* REVISIT: can nds32 profile without halting? */ +- if (target->state != TARGET_HALTED) { +- LOG_WARNING("target %s is not halted (profiling)", target->cmd_name); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- if (max_num_samples < iteration) +- iteration = max_num_samples; +- +- int pc_regnum = nds32->register_map(nds32, PC); +- aice_profiling(aice, 10, iteration, pc_regnum, samples, num_samples); +- +- register_cache_invalidate(nds32->core_cache); +- +- return ERROR_OK; +-} +- +-int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address, +- uint32_t size, const uint8_t *buffer) +-{ +- if ((nds32->active_syscall_id == NDS32_SYSCALL_FSTAT) || +- (nds32->active_syscall_id == NDS32_SYSCALL_STAT)) { +- /* If doing GDB file-I/O, target should convert 'struct stat' +- * from gdb-format to target-format */ +- uint8_t stat_buffer[NDS32_STRUCT_STAT_SIZE]; +- /* st_dev 2 */ +- stat_buffer[0] = buffer[3]; +- stat_buffer[1] = buffer[2]; +- /* st_ino 2 */ +- stat_buffer[2] = buffer[7]; +- stat_buffer[3] = buffer[6]; +- /* st_mode 4 */ +- stat_buffer[4] = buffer[11]; +- stat_buffer[5] = buffer[10]; +- stat_buffer[6] = buffer[9]; +- stat_buffer[7] = buffer[8]; +- /* st_nlink 2 */ +- stat_buffer[8] = buffer[15]; +- stat_buffer[9] = buffer[16]; +- /* st_uid 2 */ +- stat_buffer[10] = buffer[19]; +- stat_buffer[11] = buffer[18]; +- /* st_gid 2 */ +- stat_buffer[12] = buffer[23]; +- stat_buffer[13] = buffer[22]; +- /* st_rdev 2 */ +- stat_buffer[14] = buffer[27]; +- stat_buffer[15] = buffer[26]; +- /* st_size 4 */ +- stat_buffer[16] = buffer[35]; +- stat_buffer[17] = buffer[34]; +- stat_buffer[18] = buffer[33]; +- stat_buffer[19] = buffer[32]; +- /* st_atime 4 */ +- stat_buffer[20] = buffer[55]; +- stat_buffer[21] = buffer[54]; +- stat_buffer[22] = buffer[53]; +- stat_buffer[23] = buffer[52]; +- /* st_spare1 4 */ +- stat_buffer[24] = 0; +- stat_buffer[25] = 0; +- stat_buffer[26] = 0; +- stat_buffer[27] = 0; +- /* st_mtime 4 */ +- stat_buffer[28] = buffer[59]; +- stat_buffer[29] = buffer[58]; +- stat_buffer[30] = buffer[57]; +- stat_buffer[31] = buffer[56]; +- /* st_spare2 4 */ +- stat_buffer[32] = 0; +- stat_buffer[33] = 0; +- stat_buffer[34] = 0; +- stat_buffer[35] = 0; +- /* st_ctime 4 */ +- stat_buffer[36] = buffer[63]; +- stat_buffer[37] = buffer[62]; +- stat_buffer[38] = buffer[61]; +- stat_buffer[39] = buffer[60]; +- /* st_spare3 4 */ +- stat_buffer[40] = 0; +- stat_buffer[41] = 0; +- stat_buffer[42] = 0; +- stat_buffer[43] = 0; +- /* st_blksize 4 */ +- stat_buffer[44] = buffer[43]; +- stat_buffer[45] = buffer[42]; +- stat_buffer[46] = buffer[41]; +- stat_buffer[47] = buffer[40]; +- /* st_blocks 4 */ +- stat_buffer[48] = buffer[51]; +- stat_buffer[49] = buffer[50]; +- stat_buffer[50] = buffer[49]; +- stat_buffer[51] = buffer[48]; +- /* st_spare4 8 */ +- stat_buffer[52] = 0; +- stat_buffer[53] = 0; +- stat_buffer[54] = 0; +- stat_buffer[55] = 0; +- stat_buffer[56] = 0; +- stat_buffer[57] = 0; +- stat_buffer[58] = 0; +- stat_buffer[59] = 0; +- +- return nds32_write_buffer(nds32->target, address, NDS32_STRUCT_STAT_SIZE, stat_buffer); +- } else if (nds32->active_syscall_id == NDS32_SYSCALL_GETTIMEOFDAY) { +- /* If doing GDB file-I/O, target should convert 'struct timeval' +- * from gdb-format to target-format */ +- uint8_t timeval_buffer[NDS32_STRUCT_TIMEVAL_SIZE]; +- timeval_buffer[0] = buffer[3]; +- timeval_buffer[1] = buffer[2]; +- timeval_buffer[2] = buffer[1]; +- timeval_buffer[3] = buffer[0]; +- timeval_buffer[4] = buffer[11]; +- timeval_buffer[5] = buffer[10]; +- timeval_buffer[6] = buffer[9]; +- timeval_buffer[7] = buffer[8]; +- +- return nds32_write_buffer(nds32->target, address, NDS32_STRUCT_TIMEVAL_SIZE, timeval_buffer); +- } +- +- return nds32_write_buffer(nds32->target, address, size, buffer); +-} +- +-int nds32_reset_halt(struct nds32 *nds32) +-{ +- LOG_INFO("reset halt as init"); +- +- struct aice_port_s *aice = target_to_aice(nds32->target); +- aice_assert_srst(aice, AICE_RESET_HOLD); +- +- return ERROR_OK; +-} +diff --git a/src/target/nds32.h b/src/target/nds32.h +deleted file mode 100644 +index d0b680a97..000000000 +--- a/src/target/nds32.h ++++ /dev/null +@@ -1,447 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_H +-#define OPENOCD_TARGET_NDS32_H +- +-#include +-#include "target.h" +-#include "target_type.h" +-#include "register.h" +-#include "breakpoints.h" +-#include "nds32_reg.h" +-#include "nds32_insn.h" +-#include "nds32_edm.h" +- +-#define NDS32_EDM_OPERATION_MAX_NUM 64 +- +-#define CHECK_RETVAL(action) \ +- do { \ +- int __retval = (action); \ +- if (__retval != ERROR_OK) { \ +- LOG_DEBUG("error while calling \"%s\"", \ +- # action); \ +- return __retval; \ +- } \ +- } while (0) +- +-/** +- * @file +- * Holds the interface to Andes cores. +- */ +- +-extern const char *nds32_debug_type_name[11]; +- +-enum nds32_debug_reason { +- NDS32_DEBUG_BREAK = 0, +- NDS32_DEBUG_BREAK_16, +- NDS32_DEBUG_INST_BREAK, +- NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE, +- NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE, +- NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE, +- NDS32_DEBUG_DEBUG_INTERRUPT, +- NDS32_DEBUG_HARDWARE_SINGLE_STEP, +- NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE, +- NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE, +- NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP, +-}; +- +-#define NDS32_STRUCT_STAT_SIZE 60 +-#define NDS32_STRUCT_TIMEVAL_SIZE 8 +- +-enum nds32_syscall_id { +- NDS32_SYSCALL_UNDEFINED = 0, +- NDS32_SYSCALL_EXIT = 1, +- NDS32_SYSCALL_OPEN = 2, +- NDS32_SYSCALL_CLOSE = 3, +- NDS32_SYSCALL_READ = 4, +- NDS32_SYSCALL_WRITE = 5, +- NDS32_SYSCALL_LSEEK = 6, +- NDS32_SYSCALL_UNLINK = 7, +- NDS32_SYSCALL_RENAME = 3001, +- NDS32_SYSCALL_FSTAT = 10, +- NDS32_SYSCALL_STAT = 15, +- NDS32_SYSCALL_GETTIMEOFDAY = 19, +- NDS32_SYSCALL_ISATTY = 3002, +- NDS32_SYSCALL_SYSTEM = 3003, +- NDS32_SYSCALL_ERRNO = 6001, +-}; +- +-#define NDS32_COMMON_MAGIC 0xADE5ADE5U +- +-struct nds32_edm { +- +- /** EDM_CFG.VER, indicate the EDM version */ +- int version; +- +- /** The number of hardware breakpoints */ +- int breakpoint_num; +- +- /** EDM_CFG.DALM, indicate if direct local memory access +- * feature is supported or not */ +- bool direct_access_local_memory; +- +- /** Support ACC_CTL register */ +- bool access_control; +- +- /** */ +- bool support_max_stop; +-}; +- +-struct nds32_cache { +- +- /** enable cache or not */ +- bool enable; +- +- /** cache sets per way */ +- int set; +- +- /** cache ways */ +- int way; +- +- /** cache line size */ +- int line_size; +- +- /** cache locking support */ +- bool lock_support; +-}; +- +-struct nds32_memory { +- +- /** ICache */ +- struct nds32_cache icache; +- +- /** DCache */ +- struct nds32_cache dcache; +- +- /** On-chip instruction local memory base */ +- int ilm_base; +- +- /** On-chip instruction local memory size */ +- int ilm_size; +- +- /** ILM base register alignment version */ +- int ilm_align_ver; +- +- /** DLM is enabled or not */ +- bool ilm_enable; +- +- /** DLM start address */ +- int ilm_start; +- +- /** DLM end address */ +- int ilm_end; +- +- /** On-chip data local memory base */ +- int dlm_base; +- +- /** On-chip data local memory size */ +- int dlm_size; +- +- /** DLM base register alignment version */ +- int dlm_align_ver; +- +- /** DLM is enabled or not */ +- bool dlm_enable; +- +- /** DLM start address */ +- int dlm_start; +- +- /** DLM end address */ +- int dlm_end; +- +- /** Memory access method */ +- enum nds_memory_access access_channel; +- +- /** Memory access mode */ +- enum nds_memory_select mode; +- +- /** Address translation */ +- bool address_translation; +-}; +- +-struct nds32_cpu_version { +- bool performance_extension; +- bool _16bit_extension; +- bool performance_extension_2; +- bool cop_fpu_extension; +- bool string_extension; +- +- int revision; +- int cpu_id_family; +- int cpu_id_version; +-}; +- +-struct nds32_mmu_config { +- int memory_protection; +- int memory_protection_version; +- bool fully_associative_tlb; +- int tlb_size; +- int tlb_ways; +- int tlb_sets; +- bool _8k_page_support; +- int extra_page_size_support; +- bool tlb_lock; +- bool hardware_page_table_walker; +- bool default_endian; +- int partition_num; +- bool invisible_tlb; +- bool vlpt; +- bool ntme; +- bool drde; +- int default_min_page_size; +- bool multiple_page_size_in_use; +-}; +- +-struct nds32_misc_config { +- bool edm; +- bool local_memory_dma; +- bool performance_monitor; +- bool high_speed_memory_port; +- bool debug_tracer; +- bool div_instruction; +- bool mac_instruction; +- int audio_isa; +- bool l2_cache; +- bool reduce_register; +- bool addr_24; +- bool interruption_level; +- int baseline_instruction; +- bool no_dx_register; +- bool implement_dependant_register; +- bool implement_dependant_sr_encoding; +- bool ifc; +- bool mcu; +- bool ex9; +- int shadow; +-}; +- +-/** +- * Represents a generic Andes core. +- */ +-struct nds32 { +- unsigned int common_magic; +- +- struct reg_cache *core_cache; +- +- /** Handle for the debug module. */ +- struct nds32_edm edm; +- +- /** Memory information */ +- struct nds32_memory memory; +- +- /** cpu version */ +- struct nds32_cpu_version cpu_version; +- +- /** MMU configuration */ +- struct nds32_mmu_config mmu_config; +- +- /** Misc configuration */ +- struct nds32_misc_config misc_config; +- +- /** Retrieve all core registers, for display. */ +- int (*full_context)(struct nds32 *nds32); +- +- /** Register mappings */ +- int (*register_map)(struct nds32 *nds32, int reg_no); +- +- /** Get debug exception virtual address */ +- int (*get_debug_reason)(struct nds32 *nds32, uint32_t *reason); +- +- /** Restore target registers may be modified in debug state */ +- int (*leave_debug_state)(struct nds32 *nds32, bool enable_watchpoint); +- +- /** Backup target registers may be modified in debug state */ +- int (*enter_debug_state)(struct nds32 *nds32, bool enable_watchpoint); +- +- /** Get address hit watchpoint */ +- int (*get_watched_address)(struct nds32 *nds32, uint32_t *address, uint32_t reason); +- +- /** maximum interrupt level */ +- uint32_t max_interrupt_level; +- +- /** current interrupt level */ +- uint32_t current_interrupt_level; +- +- uint32_t watched_address; +- +- /** Flag reporting whether virtual hosting is active. */ +- bool virtual_hosting; +- +- /** Flag reporting whether continue/step hits syscall or not */ +- bool hit_syscall; +- +- /** Value to be returned by virtual hosting SYS_ERRNO request. */ +- int virtual_hosting_errno; +- +- /** Flag reporting whether syscall is aborted */ +- bool virtual_hosting_ctrl_c; +- +- /** Record syscall ID for other operations to do special processing for target */ +- int active_syscall_id; +- +- struct breakpoint syscall_break; +- +- /** Flag reporting whether global stop is active. */ +- bool global_stop; +- +- /** Flag reporting whether to use soft-reset-halt or not as issuing reset-halt. */ +- bool soft_reset_halt; +- +- /** reset-halt as target examine */ +- bool reset_halt_as_examine; +- +- /** backup/restore target EDM_CTL value. As debugging target debug +- * handler, it should be true. */ +- bool keep_target_edm_ctl; +- +- /* Value of $EDM_CTL before target enters debug mode */ +- uint32_t backup_edm_ctl; +- +- /** always use word-aligned address to access memory */ +- bool word_access_mem; +- +- /** EDM passcode for debugging secure MCU */ +- char *edm_passcode; +- +- /** current privilege_level if using secure MCU. value 0 is the highest level. */ +- int privilege_level; +- +- /** Period to wait after SRST. */ +- uint32_t boot_time; +- +- /** Flag to indicate HSS steps into ISR or not */ +- bool step_isr_enable; +- +- /** Flag to indicate register table is ready or not */ +- bool init_arch_info_after_halted; +- +- /** Flag to indicate audio-extension is enabled or not */ +- bool audio_enable; +- +- /** Flag to indicate fpu-extension is enabled or not */ +- bool fpu_enable; +- +- /* Andes Core has mixed endian model. Instruction is always big-endian. +- * Data may be big or little endian. Device registers may have different +- * endian from data and instruction. */ +- /** Endian of data memory */ +- enum target_endianness data_endian; +- +- /** Endian of device registers */ +- enum target_endianness device_reg_endian; +- +- /** Flag to indicate if auto convert software breakpoints to +- * hardware breakpoints or not in ROM */ +- bool auto_convert_hw_bp; +- +- /* Flag to indicate the target is attached by debugger or not */ +- bool attached; +- +- /** Backpointer to the target. */ +- struct target *target; +- +- void *arch_info; +-}; +- +-struct nds32_reg { +- int32_t num; +- uint8_t value[8]; +- struct target *target; +- struct nds32 *nds32; +- bool enable; +-}; +- +-struct nds32_edm_operation { +- uint32_t reg_no; +- uint32_t value; +-}; +- +-extern int nds32_config(struct nds32 *nds32); +-extern int nds32_init_arch_info(struct target *target, struct nds32 *nds32); +-extern int nds32_full_context(struct nds32 *nds32); +-extern int nds32_arch_state(struct target *target); +-extern int nds32_add_software_breakpoint(struct target *target, +- struct breakpoint *breakpoint); +-extern int nds32_remove_software_breakpoint(struct target *target, +- struct breakpoint *breakpoint); +- +-extern int nds32_get_gdb_reg_list(struct target *target, +- struct reg **reg_list[], int *reg_list_size, +- enum target_register_class reg_class); +- +-extern int nds32_write_buffer(struct target *target, uint32_t address, +- uint32_t size, const uint8_t *buffer); +-extern int nds32_read_buffer(struct target *target, uint32_t address, +- uint32_t size, uint8_t *buffer); +-extern int nds32_read_memory(struct target *target, uint32_t address, +- uint32_t size, uint32_t count, uint8_t *buffer); +-extern int nds32_write_memory(struct target *target, uint32_t address, +- uint32_t size, uint32_t count, const uint8_t *buffer); +- +-extern int nds32_init_register_table(struct nds32 *nds32); +-extern int nds32_init_memory_info(struct nds32 *nds32); +-extern int nds32_restore_context(struct target *target); +-extern int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value); +-extern int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value); +- +-extern int nds32_edm_config(struct nds32 *nds32); +-extern int nds32_cache_sync(struct target *target, target_addr_t address, uint32_t length); +-extern int nds32_mmu(struct target *target, int *enabled); +-extern int nds32_virtual_to_physical(struct target *target, target_addr_t address, +- target_addr_t *physical); +-extern int nds32_read_phys_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, uint8_t *buffer); +-extern int nds32_write_phys_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, const uint8_t *buffer); +-extern uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address); +-extern int nds32_examine_debug_reason(struct nds32 *nds32); +-extern int nds32_step(struct target *target, int current, +- target_addr_t address, int handle_breakpoints); +-extern int nds32_target_state(struct nds32 *nds32, enum target_state *state); +-extern int nds32_halt(struct target *target); +-extern int nds32_poll(struct target *target); +-extern int nds32_resume(struct target *target, int current, +- target_addr_t address, int handle_breakpoints, int debug_execution); +-extern int nds32_assert_reset(struct target *target); +-extern int nds32_init(struct nds32 *nds32); +-extern int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info); +-extern int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address, +- uint32_t size, const uint8_t *buffer); +-extern int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c); +-extern int nds32_reset_halt(struct nds32 *nds32); +-extern int nds32_login(struct nds32 *nds32); +-extern int nds32_profiling(struct target *target, uint32_t *samples, +- uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds); +- +-/** Convert target handle to generic Andes target state handle. */ +-static inline struct nds32 *target_to_nds32(struct target *target) +-{ +- assert(target); +- return target->arch_info; +-} +- +-/** */ +-static inline struct aice_port_s *target_to_aice(struct target *target) +-{ +- assert(target); +- return target->tap->priv; +-} +- +-static inline bool is_nds32(struct nds32 *nds32) +-{ +- assert(nds32); +- return nds32->common_magic == NDS32_COMMON_MAGIC; +-} +- +-static inline bool nds32_reach_max_interrupt_level(struct nds32 *nds32) +-{ +- assert(nds32); +- return nds32->max_interrupt_level == nds32->current_interrupt_level; +-} +- +-#endif /* OPENOCD_TARGET_NDS32_H */ +diff --git a/src/target/nds32_aice.c b/src/target/nds32_aice.c +deleted file mode 100644 +index 8dc4d7795..000000000 +--- a/src/target/nds32_aice.c ++++ /dev/null +@@ -1,147 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes technology. * +- * Hsiangkai Wang * +- ***************************************************************************/ +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include "nds32_aice.h" +- +-int aice_read_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t *val) +-{ +- if (!aice->port->api->read_reg_64) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->read_reg_64(aice->coreid, num, val); +-} +- +-int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val) +-{ +- if (!aice->port->api->write_reg_64) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->write_reg_64(aice->coreid, num, val); +-} +- +-int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address, +- target_addr_t *physical_address) +-{ +- if (!aice->port->api->read_tlb) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->read_tlb(aice->coreid, virtual_address, physical_address); +-} +- +-int aice_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address) +-{ +- if (!aice->port->api->cache_ctl) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->cache_ctl(aice->coreid, subtype, address); +-} +- +-int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times) +-{ +- if (!aice->port->api->set_retry_times) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->set_retry_times(a_retry_times); +-} +- +-int aice_program_edm(struct aice_port_s *aice, char *command_sequence) +-{ +- if (!aice->port->api->program_edm) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->program_edm(aice->coreid, command_sequence); +-} +- +-int aice_set_command_mode(struct aice_port_s *aice, +- enum aice_command_mode command_mode) +-{ +- if (!aice->port->api->set_command_mode) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->set_command_mode(command_mode); +-} +- +-int aice_execute(struct aice_port_s *aice, uint32_t *instructions, +- uint32_t instruction_num) +-{ +- if (!aice->port->api->execute) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->execute(aice->coreid, instructions, instruction_num); +-} +- +-int aice_set_custom_srst_script(struct aice_port_s *aice, const char *script) +-{ +- if (!aice->port->api->set_custom_srst_script) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->set_custom_srst_script(script); +-} +- +-int aice_set_custom_trst_script(struct aice_port_s *aice, const char *script) +-{ +- if (!aice->port->api->set_custom_trst_script) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->set_custom_trst_script(script); +-} +- +-int aice_set_custom_restart_script(struct aice_port_s *aice, const char *script) +-{ +- if (!aice->port->api->set_custom_restart_script) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->set_custom_restart_script(script); +-} +- +-int aice_set_count_to_check_dbger(struct aice_port_s *aice, uint32_t count_to_check) +-{ +- if (!aice->port->api->set_count_to_check_dbger) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->set_count_to_check_dbger(count_to_check); +-} +- +-int aice_profiling(struct aice_port_s *aice, uint32_t interval, uint32_t iteration, +- uint32_t reg_no, uint32_t *samples, uint32_t *num_samples) +-{ +- if (!aice->port->api->profiling) { +- LOG_WARNING("Not implemented: %s", __func__); +- return ERROR_FAIL; +- } +- +- return aice->port->api->profiling(aice->coreid, interval, iteration, +- reg_no, samples, num_samples); +-} +diff --git a/src/target/nds32_aice.h b/src/target/nds32_aice.h +deleted file mode 100644 +index 2a6c879ff..000000000 +--- a/src/target/nds32_aice.h ++++ /dev/null +@@ -1,150 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes technology. * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_AICE_H +-#define OPENOCD_TARGET_NDS32_AICE_H +- +-#include +- +-int aice_read_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t *val); +-int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val); +-int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address, +- target_addr_t *physical_address); +-int aice_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address); +-int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times); +-int aice_program_edm(struct aice_port_s *aice, char *command_sequence); +-int aice_set_command_mode(struct aice_port_s *aice, +- enum aice_command_mode command_mode); +-int aice_execute(struct aice_port_s *aice, uint32_t *instructions, +- uint32_t instruction_num); +-int aice_set_custom_srst_script(struct aice_port_s *aice, const char *script); +-int aice_set_custom_trst_script(struct aice_port_s *aice, const char *script); +-int aice_set_custom_restart_script(struct aice_port_s *aice, const char *script); +-int aice_set_count_to_check_dbger(struct aice_port_s *aice, uint32_t count_to_check); +-int aice_profiling(struct aice_port_s *aice, uint32_t interval, uint32_t iteration, +- uint32_t reg_no, uint32_t *samples, uint32_t *num_samples); +- +-static inline int aice_open(struct aice_port_s *aice, struct aice_port_param_s *param) +-{ +- return aice->port->api->open(param); +-} +- +-static inline int aice_close(struct aice_port_s *aice) +-{ +- return aice->port->api->close(); +-} +- +-static inline int aice_reset(struct aice_port_s *aice) +-{ +- return aice->port->api->reset(); +-} +- +-static inline int aice_assert_srst(struct aice_port_s *aice, +- enum aice_srst_type_s srst) +-{ +- return aice->port->api->assert_srst(aice->coreid, srst); +-} +- +-static inline int aice_run(struct aice_port_s *aice) +-{ +- return aice->port->api->run(aice->coreid); +-} +- +-static inline int aice_halt(struct aice_port_s *aice) +-{ +- return aice->port->api->halt(aice->coreid); +-} +- +-static inline int aice_step(struct aice_port_s *aice) +-{ +- return aice->port->api->step(aice->coreid); +-} +- +-static inline int aice_read_register(struct aice_port_s *aice, uint32_t num, +- uint32_t *val) +-{ +- return aice->port->api->read_reg(aice->coreid, num, val); +-} +- +-static inline int aice_write_register(struct aice_port_s *aice, uint32_t num, +- uint32_t val) +-{ +- return aice->port->api->write_reg(aice->coreid, num, val); +-} +- +-static inline int aice_read_debug_reg(struct aice_port_s *aice, uint32_t addr, +- uint32_t *val) +-{ +- return aice->port->api->read_debug_reg(aice->coreid, addr, val); +-} +- +-static inline int aice_write_debug_reg(struct aice_port_s *aice, uint32_t addr, +- const uint32_t val) +-{ +- return aice->port->api->write_debug_reg(aice->coreid, addr, val); +-} +- +-static inline int aice_read_mem_unit(struct aice_port_s *aice, uint32_t addr, +- uint32_t size, uint32_t count, uint8_t *buffer) +-{ +- return aice->port->api->read_mem_unit(aice->coreid, addr, size, count, buffer); +-} +- +-static inline int aice_write_mem_unit(struct aice_port_s *aice, uint32_t addr, +- uint32_t size, uint32_t count, const uint8_t *buffer) +-{ +- return aice->port->api->write_mem_unit(aice->coreid, addr, size, count, buffer); +-} +- +-static inline int aice_read_mem_bulk(struct aice_port_s *aice, uint32_t addr, +- uint32_t length, uint8_t *buffer) +-{ +- return aice->port->api->read_mem_bulk(aice->coreid, addr, length, buffer); +-} +- +-static inline int aice_write_mem_bulk(struct aice_port_s *aice, uint32_t addr, +- uint32_t length, const uint8_t *buffer) +-{ +- return aice->port->api->write_mem_bulk(aice->coreid, addr, length, buffer); +-} +- +-static inline int aice_idcode(struct aice_port_s *aice, uint32_t *idcode, +- uint8_t *num_of_idcode) +-{ +- return aice->port->api->idcode(idcode, num_of_idcode); +-} +- +-static inline int aice_state(struct aice_port_s *aice, +- enum aice_target_state_s *state) +-{ +- return aice->port->api->state(aice->coreid, state); +-} +- +-static inline int aice_set_jtag_clock(struct aice_port_s *aice, uint32_t a_clock) +-{ +- return aice->port->api->set_jtag_clock(a_clock); +-} +- +-static inline int aice_memory_access(struct aice_port_s *aice, +- enum nds_memory_access a_access) +-{ +- return aice->port->api->memory_access(aice->coreid, a_access); +-} +- +-static inline int aice_memory_mode(struct aice_port_s *aice, +- enum nds_memory_select mem_select) +-{ +- return aice->port->api->memory_mode(aice->coreid, mem_select); +-} +- +-static inline int aice_set_data_endian(struct aice_port_s *aice, +- enum aice_target_endian target_data_endian) +-{ +- return aice->port->api->set_data_endian(aice->coreid, target_data_endian); +-} +- +-#endif /* OPENOCD_TARGET_NDS32_AICE_H */ +diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c +deleted file mode 100644 +index 37f7648c9..000000000 +--- a/src/target/nds32_cmd.c ++++ /dev/null +@@ -1,1123 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include "nds32.h" +-#include "nds32_aice.h" +-#include "nds32_disassembler.h" +- +-extern struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM]; +-extern uint32_t nds32_edm_ops_num; +- +-static const char *const nds_memory_access_name[] = { +- "BUS", +- "CPU", +-}; +- +-static const char *const nds_memory_select_name[] = { +- "AUTO", +- "MEM", +- "ILM", +- "DLM", +-}; +- +-COMMAND_HANDLER(handle_nds32_dssim_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "on") == 0) +- nds32->step_isr_enable = true; +- if (strcmp(CMD_ARGV[0], "off") == 0) +- nds32->step_isr_enable = false; +- } +- +- command_print(CMD, "%s: $INT_MASK.DSSIM: %d", target_name(target), +- nds32->step_isr_enable); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_memory_access_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "bus") == 0) +- memory->access_channel = NDS_MEMORY_ACC_BUS; +- else if (strcmp(CMD_ARGV[0], "cpu") == 0) +- memory->access_channel = NDS_MEMORY_ACC_CPU; +- else /* default access channel is NDS_MEMORY_ACC_CPU */ +- memory->access_channel = NDS_MEMORY_ACC_CPU; +- +- LOG_DEBUG("memory access channel is changed to %s", +- nds_memory_access_name[memory->access_channel]); +- +- aice_memory_access(aice, memory->access_channel); +- } else { +- command_print(CMD, "%s: memory access channel: %s", +- target_name(target), +- nds_memory_access_name[memory->access_channel]); +- } +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_memory_mode_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- +- if (nds32->edm.access_control == false) { +- command_print(CMD, "%s does not support ACC_CTL. " +- "Set memory mode to MEMORY", target_name(target)); +- nds32->memory.mode = NDS_MEMORY_SELECT_MEM; +- } else if (nds32->edm.direct_access_local_memory == false) { +- command_print(CMD, "%s does not support direct access " +- "local memory. Set memory mode to MEMORY", +- target_name(target)); +- nds32->memory.mode = NDS_MEMORY_SELECT_MEM; +- +- /* set to ACC_CTL */ +- aice_memory_mode(aice, nds32->memory.mode); +- } else { +- if (strcmp(CMD_ARGV[0], "auto") == 0) { +- nds32->memory.mode = NDS_MEMORY_SELECT_AUTO; +- } else if (strcmp(CMD_ARGV[0], "mem") == 0) { +- nds32->memory.mode = NDS_MEMORY_SELECT_MEM; +- } else if (strcmp(CMD_ARGV[0], "ilm") == 0) { +- if (nds32->memory.ilm_base == 0) +- command_print(CMD, "%s does not support ILM", +- target_name(target)); +- else +- nds32->memory.mode = NDS_MEMORY_SELECT_ILM; +- } else if (strcmp(CMD_ARGV[0], "dlm") == 0) { +- if (nds32->memory.dlm_base == 0) +- command_print(CMD, "%s does not support DLM", +- target_name(target)); +- else +- nds32->memory.mode = NDS_MEMORY_SELECT_DLM; +- } +- +- /* set to ACC_CTL */ +- aice_memory_mode(aice, nds32->memory.mode); +- } +- } +- +- command_print(CMD, "%s: memory mode: %s", +- target_name(target), +- nds_memory_select_name[nds32->memory.mode]); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_cache_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_cache *icache = &(nds32->memory.icache); +- struct nds32_cache *dcache = &(nds32->memory.dcache); +- int result; +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- +- if (strcmp(CMD_ARGV[0], "invalidate") == 0) { +- if ((dcache->line_size != 0) && (dcache->enable == true)) { +- /* D$ write back */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0); +- if (result != ERROR_OK) { +- command_print(CMD, "%s: Write back data cache...failed", +- target_name(target)); +- return result; +- } +- +- command_print(CMD, "%s: Write back data cache...done", +- target_name(target)); +- +- /* D$ invalidate */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0); +- if (result != ERROR_OK) { +- command_print(CMD, "%s: Invalidate data cache...failed", +- target_name(target)); +- return result; +- } +- +- command_print(CMD, "%s: Invalidate data cache...done", +- target_name(target)); +- } else { +- if (dcache->line_size == 0) +- command_print(CMD, "%s: No data cache", +- target_name(target)); +- else +- command_print(CMD, "%s: Data cache disabled", +- target_name(target)); +- } +- +- if ((icache->line_size != 0) && (icache->enable == true)) { +- /* I$ invalidate */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0); +- if (result != ERROR_OK) { +- command_print(CMD, "%s: Invalidate instruction cache...failed", +- target_name(target)); +- return result; +- } +- +- command_print(CMD, "%s: Invalidate instruction cache...done", +- target_name(target)); +- } else { +- if (icache->line_size == 0) +- command_print(CMD, "%s: No instruction cache", +- target_name(target)); +- else +- command_print(CMD, "%s: Instruction cache disabled", +- target_name(target)); +- } +- } else +- command_print(CMD, "No valid parameter"); +- } +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_icache_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_cache *icache = &(nds32->memory.icache); +- int result; +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- +- if (icache->line_size == 0) { +- command_print(CMD, "%s: No instruction cache", +- target_name(target)); +- return ERROR_OK; +- } +- +- if (strcmp(CMD_ARGV[0], "invalidate") == 0) { +- if (icache->enable == true) { +- /* I$ invalidate */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0); +- if (result != ERROR_OK) { +- command_print(CMD, "%s: Invalidate instruction cache...failed", +- target_name(target)); +- return result; +- } +- +- command_print(CMD, "%s: Invalidate instruction cache...done", +- target_name(target)); +- } else { +- command_print(CMD, "%s: Instruction cache disabled", +- target_name(target)); +- } +- } else if (strcmp(CMD_ARGV[0], "enable") == 0) { +- uint32_t value; +- nds32_get_mapped_reg(nds32, IR8, &value); +- nds32_set_mapped_reg(nds32, IR8, value | 0x1); +- } else if (strcmp(CMD_ARGV[0], "disable") == 0) { +- uint32_t value; +- nds32_get_mapped_reg(nds32, IR8, &value); +- nds32_set_mapped_reg(nds32, IR8, value & ~0x1); +- } else if (strcmp(CMD_ARGV[0], "dump") == 0) { +- /* TODO: dump cache content */ +- } else { +- command_print(CMD, "%s: No valid parameter", target_name(target)); +- } +- } +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_dcache_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_cache *dcache = &(nds32->memory.dcache); +- int result; +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- +- if (dcache->line_size == 0) { +- command_print(CMD, "%s: No data cache", target_name(target)); +- return ERROR_OK; +- } +- +- if (strcmp(CMD_ARGV[0], "invalidate") == 0) { +- if (dcache->enable == true) { +- /* D$ write back */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0); +- if (result != ERROR_OK) { +- command_print(CMD, "%s: Write back data cache...failed", +- target_name(target)); +- return result; +- } +- +- command_print(CMD, "%s: Write back data cache...done", +- target_name(target)); +- +- /* D$ invalidate */ +- result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0); +- if (result != ERROR_OK) { +- command_print(CMD, "%s: Invalidate data cache...failed", +- target_name(target)); +- return result; +- } +- +- command_print(CMD, "%s: Invalidate data cache...done", +- target_name(target)); +- } else { +- command_print(CMD, "%s: Data cache disabled", +- target_name(target)); +- } +- } else if (strcmp(CMD_ARGV[0], "enable") == 0) { +- uint32_t value; +- nds32_get_mapped_reg(nds32, IR8, &value); +- nds32_set_mapped_reg(nds32, IR8, value | 0x2); +- } else if (strcmp(CMD_ARGV[0], "disable") == 0) { +- uint32_t value; +- nds32_get_mapped_reg(nds32, IR8, &value); +- nds32_set_mapped_reg(nds32, IR8, value & ~0x2); +- } else if (strcmp(CMD_ARGV[0], "dump") == 0) { +- /* TODO: dump cache content */ +- } else { +- command_print(CMD, "%s: No valid parameter", target_name(target)); +- } +- } +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_auto_break_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "on") == 0) +- nds32->auto_convert_hw_bp = true; +- if (strcmp(CMD_ARGV[0], "off") == 0) +- nds32->auto_convert_hw_bp = false; +- } +- +- if (nds32->auto_convert_hw_bp) +- command_print(CMD, "%s: convert sw break to hw break on ROM: on", +- target_name(target)); +- else +- command_print(CMD, "%s: convert sw break to hw break on ROM: off", +- target_name(target)); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_virtual_hosting_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "on") == 0) +- nds32->virtual_hosting = true; +- if (strcmp(CMD_ARGV[0], "off") == 0) +- nds32->virtual_hosting = false; +- } +- +- if (nds32->virtual_hosting) +- command_print(CMD, "%s: virtual hosting: on", target_name(target)); +- else +- command_print(CMD, "%s: virtual hosting: off", target_name(target)); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_global_stop_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "on") == 0) +- nds32->global_stop = true; +- if (strcmp(CMD_ARGV[0], "off") == 0) +- nds32->global_stop = false; +- } +- +- if (nds32->global_stop) +- LOG_INFO("%s: global stop: on", target_name(target)); +- else +- LOG_INFO("%s: global stop: off", target_name(target)); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_soft_reset_halt_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "on") == 0) +- nds32->soft_reset_halt = true; +- if (strcmp(CMD_ARGV[0], "off") == 0) +- nds32->soft_reset_halt = false; +- } +- +- if (nds32->soft_reset_halt) +- LOG_INFO("%s: soft-reset-halt: on", target_name(target)); +- else +- LOG_INFO("%s: soft-reset-halt: off", target_name(target)); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_boot_time_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], nds32->boot_time); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_login_edm_passcode_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- nds32->edm_passcode = strdup(CMD_ARGV[0]); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_login_edm_operation_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 1) { +- +- uint32_t misc_reg_no; +- uint32_t data; +- +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], misc_reg_no); +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], data); +- +- if (nds32_edm_ops_num >= NDS32_EDM_OPERATION_MAX_NUM) +- return ERROR_FAIL; +- +- /* Just save the operation. Execute it in nds32_login() */ +- nds32_edm_ops[nds32_edm_ops_num].reg_no = misc_reg_no; +- nds32_edm_ops[nds32_edm_ops_num].value = data; +- nds32_edm_ops_num++; +- } else +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_reset_halt_as_init_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "on") == 0) +- nds32->reset_halt_as_examine = true; +- if (strcmp(CMD_ARGV[0], "off") == 0) +- nds32->reset_halt_as_examine = false; +- } +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_keep_target_edm_ctl_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "on") == 0) +- nds32->keep_target_edm_ctl = true; +- if (strcmp(CMD_ARGV[0], "off") == 0) +- nds32->keep_target_edm_ctl = false; +- } +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_decode_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 1) { +- +- uint32_t addr; +- uint32_t insn_count; +- uint32_t opcode; +- uint32_t read_addr; +- uint32_t i; +- struct nds32_instruction instruction; +- +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], insn_count); +- +- read_addr = addr; +- i = 0; +- while (i < insn_count) { +- if (nds32_read_opcode(nds32, read_addr, &opcode) != ERROR_OK) +- return ERROR_FAIL; +- if (nds32_evaluate_opcode(nds32, opcode, read_addr, &instruction) != ERROR_OK) +- return ERROR_FAIL; +- +- command_print(CMD, "%s", instruction.text); +- +- read_addr += instruction.instruction_size; +- i++; +- } +- } else if (CMD_ARGC == 1) { +- +- uint32_t addr; +- uint32_t opcode; +- struct nds32_instruction instruction; +- +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); +- +- if (nds32_read_opcode(nds32, addr, &opcode) != ERROR_OK) +- return ERROR_FAIL; +- if (nds32_evaluate_opcode(nds32, opcode, addr, &instruction) != ERROR_OK) +- return ERROR_FAIL; +- +- command_print(CMD, "%s", instruction.text); +- } else +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_word_access_mem_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- if (CMD_ARGC > 0) { +- if (strcmp(CMD_ARGV[0], "on") == 0) +- nds32->word_access_mem = true; +- if (strcmp(CMD_ARGV[0], "off") == 0) +- nds32->word_access_mem = false; +- } +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_query_target_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- command_print(CMD, "OCD"); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_query_endian_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- uint32_t value_psw; +- nds32_get_mapped_reg(nds32, IR0, &value_psw); +- +- if (value_psw & 0x20) +- command_print(CMD, "%s: BE", target_name(target)); +- else +- command_print(CMD, "%s: LE", target_name(target)); +- +- return ERROR_OK; +-} +- +-COMMAND_HANDLER(handle_nds32_query_cpuid_command) +-{ +- struct target *target = get_current_target(CMD_CTX); +- struct nds32 *nds32 = target_to_nds32(target); +- +- if (!is_nds32(nds32)) { +- command_print(CMD, "current target isn't an Andes core"); +- return ERROR_FAIL; +- } +- +- command_print(CMD, "CPUID: %s", target_name(target)); +- +- return ERROR_OK; +-} +- +-static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- const char *cmd_name = Jim_GetString(argv[0], NULL); +- +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- +- if (goi.argc < 3) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s
", cmd_name); +- return JIM_ERR; +- } +- +- int e; +- jim_wide address; +- e = jim_getopt_wide(&goi, &address); +- if (e != JIM_OK) +- return e; +- +- jim_wide count; +- e = jim_getopt_wide(&goi, &count); +- if (e != JIM_OK) +- return e; +- +- uint32_t *data = malloc(count * sizeof(uint32_t)); +- if (!data) +- return JIM_ERR; +- +- jim_wide i; +- for (i = 0; i < count; i++) { +- jim_wide tmp; +- e = jim_getopt_wide(&goi, &tmp); +- if (e != JIM_OK) { +- free(data); +- return e; +- } +- data[i] = (uint32_t)tmp; +- } +- +- /* all args must be consumed */ +- if (goi.argc != 0) { +- free(data); +- return JIM_ERR; +- } +- +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); +- int result; +- +- result = target_write_buffer(target, address, count * 4, (const uint8_t *)data); +- +- free(data); +- +- return result; +-} +- +-static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- const char *cmd_name = Jim_GetString(argv[0], NULL); +- +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- +- if (goi.argc < 3) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s # of pairs [
]+", cmd_name); +- return JIM_ERR; +- } +- +- int e; +- jim_wide num_of_pairs; +- e = jim_getopt_wide(&goi, &num_of_pairs); +- if (e != JIM_OK) +- return e; +- +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); +- struct aice_port_s *aice = target_to_aice(target); +- int result; +- uint32_t address; +- uint32_t data; +- jim_wide i; +- +- aice_set_command_mode(aice, AICE_COMMAND_MODE_PACK); +- for (i = 0; i < num_of_pairs; i++) { +- jim_wide tmp; +- e = jim_getopt_wide(&goi, &tmp); +- if (e != JIM_OK) +- break; +- address = (uint32_t)tmp; +- +- e = jim_getopt_wide(&goi, &tmp); +- if (e != JIM_OK) +- break; +- data = (uint32_t)tmp; +- +- result = target_write_buffer(target, address, 4, (const uint8_t *)&data); +- if (result != ERROR_OK) +- break; +- } +- aice_set_command_mode(aice, AICE_COMMAND_MODE_NORMAL); +- +- /* all args must be consumed */ +- if (goi.argc != 0) +- return JIM_ERR; +- +- return ERROR_OK; +-} +- +-static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- const char *cmd_name = Jim_GetString(argv[0], NULL); +- +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- +- if (goi.argc < 2) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s
", cmd_name); +- return JIM_ERR; +- } +- +- int e; +- jim_wide address; +- e = jim_getopt_wide(&goi, &address); +- if (e != JIM_OK) +- return e; +- +- jim_wide count; +- e = jim_getopt_wide(&goi, &count); +- if (e != JIM_OK) +- return e; +- +- /* all args must be consumed */ +- if (goi.argc != 0) +- return JIM_ERR; +- +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); +- uint32_t *data = malloc(count * sizeof(uint32_t)); +- int result; +- result = target_read_buffer(target, address, count * 4, (uint8_t *)data); +- char data_str[12]; +- +- jim_wide i; +- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); +- for (i = 0; i < count; i++) { +- sprintf(data_str, "0x%08" PRIx32 " ", data[i]); +- Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL); +- } +- +- free(data); +- +- return result; +-} +- +-static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- const char *cmd_name = Jim_GetString(argv[0], NULL); +- +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- +- if (goi.argc < 1) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s ", cmd_name); +- return JIM_ERR; +- } +- +- int e; +- const char *edm_sr_name; +- int edm_sr_name_len; +- e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len); +- if (e != JIM_OK) +- return e; +- +- /* all args must be consumed */ +- if (goi.argc != 0) +- return JIM_ERR; +- +- uint32_t edm_sr_number; +- uint32_t edm_sr_value; +- if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0) +- edm_sr_number = NDS_EDM_SR_EDM_DTR; +- else if (strncmp(edm_sr_name, "edmsw", edm_sr_name_len) == 0) +- edm_sr_number = NDS_EDM_SR_EDMSW; +- else +- return ERROR_FAIL; +- +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); +- struct aice_port_s *aice = target_to_aice(target); +- char data_str[11]; +- +- aice_read_debug_reg(aice, edm_sr_number, &edm_sr_value); +- +- sprintf(data_str, "0x%08" PRIx32, edm_sr_value); +- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); +- Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL); +- +- return ERROR_OK; +-} +- +-static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- const char *cmd_name = Jim_GetString(argv[0], NULL); +- +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- +- if (goi.argc < 2) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s ", cmd_name); +- return JIM_ERR; +- } +- +- int e; +- const char *edm_sr_name; +- int edm_sr_name_len; +- e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len); +- if (e != JIM_OK) +- return e; +- +- jim_wide value; +- e = jim_getopt_wide(&goi, &value); +- if (e != JIM_OK) +- return e; +- +- /* all args must be consumed */ +- if (goi.argc != 0) +- return JIM_ERR; +- +- uint32_t edm_sr_number; +- if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0) +- edm_sr_number = NDS_EDM_SR_EDM_DTR; +- else +- return ERROR_FAIL; +- +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); +- struct aice_port_s *aice = target_to_aice(target); +- +- aice_write_debug_reg(aice, edm_sr_number, value); +- +- return ERROR_OK; +-} +- +-static const struct command_registration nds32_query_command_handlers[] = { +- { +- .name = "target", +- .handler = handle_nds32_query_target_command, +- .mode = COMMAND_EXEC, +- .usage = "", +- .help = "reply 'OCD' for gdb to identify server-side is OpenOCD", +- }, +- { +- .name = "endian", +- .handler = handle_nds32_query_endian_command, +- .mode = COMMAND_EXEC, +- .usage = "", +- .help = "query target endian", +- }, +- { +- .name = "cpuid", +- .handler = handle_nds32_query_cpuid_command, +- .mode = COMMAND_EXEC, +- .usage = "", +- .help = "query CPU ID", +- }, +- +- COMMAND_REGISTRATION_DONE +-}; +- +-static const struct command_registration nds32_exec_command_handlers[] = { +- { +- .name = "dssim", +- .handler = handle_nds32_dssim_command, +- .mode = COMMAND_EXEC, +- .usage = "['on'|'off']", +- .help = "display/change $INT_MASK.DSSIM status", +- }, +- { +- .name = "mem_access", +- .handler = handle_nds32_memory_access_command, +- .mode = COMMAND_EXEC, +- .usage = "['bus'|'cpu']", +- .help = "display/change memory access channel", +- }, +- { +- .name = "mem_mode", +- .handler = handle_nds32_memory_mode_command, +- .mode = COMMAND_EXEC, +- .usage = "['auto'|'mem'|'ilm'|'dlm']", +- .help = "display/change memory mode", +- }, +- { +- .name = "cache", +- .handler = handle_nds32_cache_command, +- .mode = COMMAND_EXEC, +- .usage = "['invalidate']", +- .help = "cache control", +- }, +- { +- .name = "icache", +- .handler = handle_nds32_icache_command, +- .mode = COMMAND_EXEC, +- .usage = "['invalidate'|'enable'|'disable'|'dump']", +- .help = "icache control", +- }, +- { +- .name = "dcache", +- .handler = handle_nds32_dcache_command, +- .mode = COMMAND_EXEC, +- .usage = "['invalidate'|'enable'|'disable'|'dump']", +- .help = "dcache control", +- }, +- { +- .name = "auto_break", +- .handler = handle_nds32_auto_break_command, +- .mode = COMMAND_EXEC, +- .usage = "['on'|'off']", +- .help = "convert software breakpoints to hardware breakpoints if needed", +- }, +- { +- .name = "virtual_hosting", +- .handler = handle_nds32_virtual_hosting_command, +- .mode = COMMAND_ANY, +- .usage = "['on'|'off']", +- .help = "turn on/off virtual hosting", +- }, +- { +- .name = "global_stop", +- .handler = handle_nds32_global_stop_command, +- .mode = COMMAND_ANY, +- .usage = "['on'|'off']", +- .help = "turn on/off global stop. After turning on, every load/store " +- "instructions will be stopped to check memory access.", +- }, +- { +- .name = "soft_reset_halt", +- .handler = handle_nds32_soft_reset_halt_command, +- .mode = COMMAND_ANY, +- .usage = "['on'|'off']", +- .help = "as issuing rest-halt, to use soft-reset-halt or not." +- "the feature is for backward-compatible.", +- }, +- { +- .name = "boot_time", +- .handler = handle_nds32_boot_time_command, +- .mode = COMMAND_CONFIG, +- .usage = "milliseconds", +- .help = "set the period to wait after srst.", +- }, +- { +- .name = "login_edm_passcode", +- .handler = handle_nds32_login_edm_passcode_command, +- .mode = COMMAND_CONFIG, +- .usage = "passcode", +- .help = "set EDM passcode for secure MCU debugging.", +- }, +- { +- .name = "login_edm_operation", +- .handler = handle_nds32_login_edm_operation_command, +- .mode = COMMAND_CONFIG, +- .usage = "misc_reg_no value", +- .help = "add EDM operations for secure MCU debugging.", +- }, +- { +- .name = "reset_halt_as_init", +- .handler = handle_nds32_reset_halt_as_init_command, +- .mode = COMMAND_CONFIG, +- .usage = "['on'|'off']", +- .help = "reset halt as openocd init.", +- }, +- { +- .name = "keep_target_edm_ctl", +- .handler = handle_nds32_keep_target_edm_ctl_command, +- .mode = COMMAND_CONFIG, +- .usage = "['on'|'off']", +- .help = "Backup/Restore target EDM_CTL register.", +- }, +- { +- .name = "decode", +- .handler = handle_nds32_decode_command, +- .mode = COMMAND_EXEC, +- .usage = "address icount", +- .help = "decode instruction.", +- }, +- { +- .name = "word_access_mem", +- .handler = handle_nds32_word_access_mem_command, +- .mode = COMMAND_ANY, +- .usage = "['on'|'off']", +- .help = "Always use word-aligned address to access memory.", +- }, +- { +- .name = "bulk_write", +- .jim_handler = jim_nds32_bulk_write, +- .mode = COMMAND_EXEC, +- .help = "Write multiple 32-bit words to target memory", +- .usage = "address count data", +- }, +- { +- .name = "multi_write", +- .jim_handler = jim_nds32_multi_write, +- .mode = COMMAND_EXEC, +- .help = "Write multiple addresses/words to target memory", +- .usage = "num_of_pairs [address data]+", +- }, +- { +- .name = "bulk_read", +- .jim_handler = jim_nds32_bulk_read, +- .mode = COMMAND_EXEC, +- .help = "Read multiple 32-bit words from target memory", +- .usage = "address count", +- }, +- { +- .name = "read_edmsr", +- .jim_handler = jim_nds32_read_edm_sr, +- .mode = COMMAND_EXEC, +- .help = "Read EDM system register", +- .usage = "['edmsw'|'edm_dtr']", +- }, +- { +- .name = "write_edmsr", +- .jim_handler = jim_nds32_write_edm_sr, +- .mode = COMMAND_EXEC, +- .help = "Write EDM system register", +- .usage = "['edm_dtr'] value", +- }, +- { +- .name = "query", +- .mode = COMMAND_EXEC, +- .help = "Andes query command group", +- .usage = "", +- .chain = nds32_query_command_handlers, +- }, +- +- COMMAND_REGISTRATION_DONE +-}; +- +-const struct command_registration nds32_command_handlers[] = { +- { +- .name = "nds", +- .mode = COMMAND_ANY, +- .help = "Andes command group", +- .usage = "", +- .chain = nds32_exec_command_handlers, +- }, +- COMMAND_REGISTRATION_DONE +-}; +diff --git a/src/target/nds32_cmd.h b/src/target/nds32_cmd.h +deleted file mode 100644 +index 15932438c..000000000 +--- a/src/target/nds32_cmd.h ++++ /dev/null +@@ -1,15 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_CMD_H +-#define OPENOCD_TARGET_NDS32_CMD_H +- +-#include +- +-extern const struct command_registration nds32_command_handlers[]; +- +-#endif /* OPENOCD_TARGET_NDS32_CMD_H */ +diff --git a/src/target/nds32_disassembler.c b/src/target/nds32_disassembler.c +deleted file mode 100644 +index eebbfe109..000000000 +--- a/src/target/nds32_disassembler.c ++++ /dev/null +@@ -1,3847 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include +-#include "nds32_disassembler.h" +- +-static const int enable4_bits[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; +- +-int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value) +-{ +- struct target *target = nds32->target; +- uint8_t value_buf[4]; +- +- if (!target_was_examined(target)) { +- LOG_ERROR("Target not examined yet"); +- return ERROR_FAIL; +- } +- +- int retval = target_read_buffer(target, address, 4, value_buf); +- +- if (retval == ERROR_OK) { +- /* instructions are always big-endian */ +- *value = be_to_h_u32(value_buf); +- +- LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "", +- address, +- *value); +- } else { +- *value = 0x0; +- LOG_DEBUG("address: 0x%8.8" PRIx32 " failed", +- address); +- } +- +- return retval; +-} +- +-static int nds32_parse_type_0(uint32_t opcode, int32_t *imm) +-{ +- *imm = opcode & 0x1FFFFFF; +- +- return ERROR_OK; +-} +- +-static int nds32_parse_type_1(uint32_t opcode, uint8_t *rt, int32_t *imm) +-{ +- *rt = (opcode >> 20) & 0x1F; +- *imm = opcode & 0xFFFFF; +- +- return ERROR_OK; +-} +- +-static int nds32_parse_type_2(uint32_t opcode, uint8_t *rt, uint8_t *ra, int32_t *imm) +-{ +- *rt = (opcode >> 20) & 0x1F; +- *ra = (opcode >> 15) & 0x1F; +- *imm = opcode & 0x7FFF; +- +- return ERROR_OK; +-} +- +-static int nds32_parse_type_3(uint32_t opcode, uint8_t *rt, uint8_t *ra, +- uint8_t *rb, int32_t *imm) +-{ +- *rt = (opcode >> 20) & 0x1F; +- *ra = (opcode >> 15) & 0x1F; +- *rb = (opcode >> 10) & 0x1F; +- *imm = opcode & 0x3FF; +- +- return ERROR_OK; +-} +- +-static int nds32_parse_type_4(uint32_t opcode, uint8_t *rt, uint8_t *ra, +- uint8_t *rb, uint8_t *rd, uint8_t *sub_opc) +-{ +- *rt = (opcode >> 20) & 0x1F; +- *ra = (opcode >> 15) & 0x1F; +- *rb = (opcode >> 10) & 0x1F; +- *rd = (opcode >> 5) & 0x1F; +- *sub_opc = opcode & 0x1F; +- +- return ERROR_OK; +-} +- +-/* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */ +-static int nds32_parse_group_0_insn(struct nds32 *nds32, uint32_t opcode, +- uint32_t address, +- struct nds32_instruction *instruction) +-{ +- uint8_t opc_6; +- +- opc_6 = instruction->info.opc_6; +- +- switch (opc_6 & 0x7) { +- case 0: /* LBI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 1: /* LHI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLHI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 2: /* LWI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLWI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 4: /* LBI.bi */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 5: /* LHI.bi */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLHI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 6: /* LWI.bi */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLWI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32 "", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_1_insn(struct nds32 *nds32, uint32_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- uint8_t opc_6; +- +- opc_6 = instruction->info.opc_6; +- +- switch (opc_6 & 0x7) { +- case 0: /* SBI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSBI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 1: /* SHI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSHI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 2: /* SWI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSWI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 4: /* SBI.bi */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSBI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 5: /* SHI.bi */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSHI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 6: /* SWI.bi */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSWI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_2_insn(struct nds32 *nds32, uint32_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- uint8_t opc_6; +- +- opc_6 = instruction->info.opc_6; +- +- switch (opc_6 & 0x7) { +- case 0: /* LBSI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBSI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 1: /* LHSI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLHSI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 3: { /* DPREFI */ +- uint8_t sub_type; +- nds32_parse_type_2(opcode, &sub_type, &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->info.sub_opc = sub_type & 0xF; +- instruction->type = NDS32_INSN_MISC; +- if (sub_type & 0x10) { /* DPREFI.d */ +- /* sign-extend */ +- instruction->info.imm = (instruction->info.imm << 17) >> 14; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tDPREFI.d\t%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.sub_opc, +- instruction->info.ra, instruction->info.imm); +- } else { /* DPREFI.w */ +- /* sign-extend */ +- instruction->info.imm = (instruction->info.imm << 17) >> 15; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tDPREFI.w\t%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", +- address, +- opcode, instruction->info.sub_opc, +- instruction->info.ra, instruction->info.imm); +- } +- } +- break; +- case 4: /* LBSI.bi */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBSI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 5: /* LHSI.bi */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLHSI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 6: /* LBGP */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- if ((instruction->info.imm >> 19) & 0x1) { /* LBSI.gp */ +- instruction->info.imm = (instruction->info.imm << 13) >> 13; +- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBSI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } else { /* LBI.gp */ +- instruction->info.imm = (instruction->info.imm << 13) >> 13; +- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_mem(struct nds32 *nds32, uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction) +-{ +- uint32_t sub_opcode = opcode & 0x3F; +- uint32_t val_ra, val_rb; +- switch (sub_opcode >> 3) { +- case 0: +- switch (sub_opcode & 0x7) { +- case 0: /* LB */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLB\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 1: /* LH */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLH\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 2: /* LW */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 4: /* LB.bi */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLB.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", +- address, +- opcode, instruction->info.rt, +- instruction->info.ra, instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 5: /* LH.bi */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLH.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 6: /* LW.bi */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLW.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- } +- break; +- case 1: +- switch (sub_opcode & 0x7) { +- case 0: /* SB */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSB\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, +- instruction->info.ra, instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 1: /* SH */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSH\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 2: /* SW */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, +- instruction->info.ra, instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 4: /* SB.bi */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSB.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 5: /* SH.bi */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSH.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 6: /* SW.bi */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSW.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- } +- break; +- case 2: +- switch (sub_opcode & 0x7) { +- case 0: /* LBS */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBS\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, +- instruction->info.ra, instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 1: /* LHS */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLHS\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 3: /* DPREF */ +- nds32_parse_type_3(opcode, &(instruction->info.sub_opc), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tDPREF\t#%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<#%" PRId32 ")]", +- address, +- opcode, instruction->info.sub_opc, +- instruction->info.ra, instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 4: /* LBS.bi */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBS.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 5: /* LHS.bi */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLHS.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- } +- break; +- case 3: +- switch (sub_opcode & 0x7) { +- case 0: /* LLW */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLLW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 1: /* SCW */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSCW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- } +- break; +- case 4: +- switch (sub_opcode & 0x7) { +- case 0: /* LBUP */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLBUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 2: /* LWUP */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLWUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- } +- break; +- case 5: +- switch (sub_opcode & 0x7) { +- case 0: /* SBUP */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSBUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- case 2: /* SWUP */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); +- nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); +- instruction->access_start = val_ra + +- (val_rb << ((instruction->info.imm >> 8) & 0x3)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSWUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- (instruction->info.imm >> 8) & 0x3); +- break; +- } +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_calculate_lsmw_access_range(struct nds32 *nds32, +- struct nds32_instruction *instruction) +-{ +- uint8_t ba; +- uint8_t id; +- uint8_t enable4; +- +- enable4 = (instruction->info.imm >> 6) & 0xF; +- ba = (instruction->info.imm >> 4) & 0x1; +- id = (instruction->info.imm >> 3) & 0x1; +- +- if (ba) { +- nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start)); +- if (id) { /* decrease */ +- /* access_end is the (last_element+1), so no need to minus 4 */ +- /* instruction->access_end -= 4; */ +- instruction->access_end = instruction->access_start; +- } else { /* increase */ +- instruction->access_start += 4; +- } +- } else { +- nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start)); +- instruction->access_end = instruction->access_start - 4; +- } +- +- if (id) { /* decrease */ +- instruction->access_start = instruction->access_end - +- 4 * (instruction->info.rd - instruction->info.rb + 1); +- instruction->access_start -= (4 * enable4_bits[enable4]); +- } else { /* increase */ +- instruction->access_end = instruction->access_start + +- 4 * (instruction->info.rd - instruction->info.rb + 1); +- instruction->access_end += (4 * enable4_bits[enable4]); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_lsmw(struct nds32 *nds32, uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction) +-{ +- if (opcode & 0x20) { /* SMW, SMWA, SMWZB */ +- switch (opcode & 0x3) { +- /* TODO */ +- case 0: /* SMW */ +- /* use rd as re */ +- nds32_parse_type_3(opcode, &(instruction->info.rb), +- &(instruction->info.ra), +- &(instruction->info.rd), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_calculate_lsmw_access_range(nds32, instruction); +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSMW\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rb, instruction->info.ra, +- instruction->info.rd, +- (instruction->info.imm >> 6) & 0xF); +- break; +- case 1: /* SMWA */ +- nds32_parse_type_3(opcode, &(instruction->info.rb), +- &(instruction->info.ra), +- &(instruction->info.rd), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_calculate_lsmw_access_range(nds32, instruction); +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSMWA\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rb, instruction->info.ra, +- instruction->info.rd, +- (instruction->info.imm >> 6) & 0xF); +- break; +- case 2: /* SMWZB */ +- nds32_parse_type_3(opcode, &(instruction->info.rb), +- &(instruction->info.ra), +- &(instruction->info.rd), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- /* TODO: calculate access_start/access_end */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSMWZB\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rb, instruction->info.ra, +- instruction->info.rd, +- (instruction->info.imm >> 6) & 0xF); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- } else { /* LMW, LMWA, LMWZB */ +- switch (opcode & 0x3) { +- case 0: /* LMW */ +- nds32_parse_type_3(opcode, &(instruction->info.rb), +- &(instruction->info.ra), +- &(instruction->info.rd), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_calculate_lsmw_access_range(nds32, instruction); +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLMW\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rb, instruction->info.ra, +- instruction->info.rd, +- (instruction->info.imm >> 6) & 0xF); +- break; +- case 1: /* LMWA */ +- nds32_parse_type_3(opcode, &(instruction->info.rb), +- &(instruction->info.ra), +- &(instruction->info.rd), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_calculate_lsmw_access_range(nds32, instruction); +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLMWA\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rb, instruction->info.ra, +- instruction->info.rd, +- (instruction->info.imm >> 6) & 0xF); +- break; +- case 2: /* LMWZB */ +- nds32_parse_type_3(opcode, &(instruction->info.rb), +- &(instruction->info.ra), +- &(instruction->info.rd), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_LOAD_STORE; +- /* TODO: calculate access_start/access_end */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLMWZB\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rb, instruction->info.ra, +- instruction->info.rd, +- (instruction->info.imm >> 6) & 0xF); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_hwgp(struct nds32 *nds32, uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction) +-{ +- switch ((opcode >> 18) & 0x3) { +- case 0: /* LHI.gp */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLHI.gp\t$r%" PRIu8 ",[#%" PRId32"]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 1: /* LHSI.gp */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLHSI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 2: /* SHI.gp */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSHI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 3: +- instruction->type = NDS32_INSN_LOAD_STORE; +- if ((opcode >> 17) & 0x1) { /* SWI.gp */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- /* sign-extend */ +- instruction->info.imm = (instruction->info.imm << 15) >> 13; +- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSWI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } else { /* LWI.gp */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- /* sign-extend */ +- instruction->info.imm = (instruction->info.imm << 15) >> 13; +- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tLWI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } +- +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_sbgp(struct nds32 *nds32, uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction) +-{ +- switch ((opcode >> 19) & 0x1) { +- case 0: /* SBI.gp */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */ +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSBI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 1: /* ADDI.gp */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */ +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tADDI.gp\t$r%" PRIu8 ",#%" PRId32 "", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_3_insn(struct nds32 *nds32, uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction) +-{ +- uint8_t opc_6; +- +- opc_6 = instruction->info.opc_6; +- +- switch (opc_6 & 0x7) { +- case 4: /* MEM */ +- nds32_parse_mem(nds32, opcode, address, instruction); +- break; +- case 5: /* LSMW */ +- nds32_parse_lsmw(nds32, opcode, address, instruction); +- break; +- case 6: /* HWGP */ +- nds32_parse_hwgp(nds32, opcode, address, instruction); +- break; +- case 7: /* SBGP */ +- nds32_parse_sbgp(nds32, opcode, address, instruction); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_alu_1(uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction) +-{ +- switch (opcode & 0x1F) { +- case 0: /* ADD */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tADD_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tADD\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 1: /* SUB */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSUB_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSUB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 "", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 2: /* AND */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tAND_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tAND\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 "", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 3: /* XOR */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tXOR_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tXOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 4: /* OR */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tOR_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 5: /* NOR */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tNOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 6: /* SLT */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSLT\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 7: /* SLTS */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSLTS\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 8: { /* SLLI */ +- uint8_t imm; +- int32_t sub_op; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &sub_op); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSLLI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 9: { /* SRLI */ +- uint8_t imm; +- int32_t sub_op; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &sub_op); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSRLI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 10: { /* SRAI */ +- uint8_t imm; +- int32_t sub_op; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &sub_op); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSRAI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 11: { /* ROTRI */ +- uint8_t imm; +- int32_t sub_op; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &sub_op); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tROTRI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 12: { /* SLL */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSLL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 13: { /* SRL */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSRL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 14: { /* SRA */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSRA\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 15: { /* ROTR */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tROTR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 16: { /* SEB */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSEB\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- } +- break; +- case 17: { /* SEH */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSEH\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- } +- break; +- case 18: /* BITC */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBITC\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 19: { /* ZEH */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tZEH\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- } +- break; +- case 20: { /* WSBH */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tWSBH\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- } +- break; +- case 21: /* OR_SRLI */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tOR_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 22: { /* DIVSR */ +- nds32_parse_type_4(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.rd), +- &(instruction->info.sub_opc)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tDIVSR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.rd); +- } +- break; +- case 23: { /* DIVR */ +- nds32_parse_type_4(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.rd), +- &(instruction->info.sub_opc)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tDIVR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.rd); +- } +- break; +- case 24: { /* SVA */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSVA\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 25: { /* SVS */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSVS\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 26: { /* CMOVZ */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tCMOVZ\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 27: { /* CMOVN */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tCMOVN\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 28: /* ADD_SRLI */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tADD_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tADD\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 29: /* SUB_SRLI */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSUB_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSUB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 30: /* AND_SRLI */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tAND_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tAND\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 31: /* XOR_SRLI */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; +- if (instruction->info.imm) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tXOR_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb, +- instruction->info.imm); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tXOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_alu_2(uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction) +-{ +- switch (opcode & 0x3F) { +- case 0: /* MAX */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMAX\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 1: /* MIN */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMIN\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 2: /* AVE */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tAVE\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 3: /* ABS */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tAVE\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 4: { /* CLIPS */ +- uint8_t imm; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &(instruction->info.imm)); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tCLIPS\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 5: { /* CLIP */ +- uint8_t imm; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &(instruction->info.imm)); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tCLIP\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 6: /* CLO */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tCLO\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 7: /* CLZ */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tCLZ\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 8: { /* BSET */ +- uint8_t imm; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &(instruction->info.imm)); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBSET\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 9: { /* BCLR */ +- uint8_t imm; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &(instruction->info.imm)); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBCLR\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 10: { /* BTGL */ +- uint8_t imm; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &(instruction->info.imm)); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBTGL\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 11: { /* BTST */ +- uint8_t imm; +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &imm, &(instruction->info.imm)); +- instruction->info.imm = imm; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBTST\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- case 12: /* BSE */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBSE\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 13: /* BSP */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBSP\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 14: /* FFB */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tFFB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 15: /* FFMISM */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tFFMISM\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 23: /* FFZMISM */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tFFZMISM\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 32: /* MFUSR */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_RESOURCE_ACCESS; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMFUSR\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, +- (instruction->info.imm >> 10) & 0x3FF); +- break; +- case 33: /* MTUSR */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_RESOURCE_ACCESS; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMTUSR\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, +- (instruction->info.imm >> 10) & 0x3FF); +- break; +- case 36: /* MUL */ +- nds32_parse_type_3(opcode, &(instruction->info.rt), +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMUL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- break; +- case 40: { /* MULTS64 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMULTS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 41: { /* MULT64 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, +- &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMULT64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 42: { /* MADDS64 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMADDS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 43: { /* MADD64 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMADD64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 44: { /* MSUBS64 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMSUBS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 45: { /* MSUB64 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMSUB64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 46: { /* DIVS */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tDIVS\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 47: { /* DIV */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tDIV\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 49: { /* MULT32 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMULT32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 51: { /* MADD32 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMADD32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 53: { /* MSUB32 */ +- uint8_t dt_val; +- nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), +- &(instruction->info.rb), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMSUB32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, +- instruction->info.rb); +- } +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_4_insn(struct nds32 *nds32, uint32_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- uint8_t opc_6; +- +- opc_6 = instruction->info.opc_6; +- +- switch (opc_6 & 0x7) { +- case 0: /* ALU_1 */ +- nds32_parse_alu_1(opcode, address, instruction); +- break; +- case 1: /* ALU_2 */ +- nds32_parse_alu_2(opcode, address, instruction); +- break; +- case 2: /* MOVI */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- /* sign-extend */ +- instruction->info.imm = (instruction->info.imm << 12) >> 12; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMOVI\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 3: /* SETHI */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSETHI\t$r%" PRIu8 ",0x%8.8" PRIx32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 4: /* JI */ +- nds32_parse_type_0(opcode, &(instruction->info.imm)); +- /* sign-extend */ +- instruction->info.imm = (instruction->info.imm << 8) >> 8; +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- if ((instruction->info.imm >> 24) & 0x1) { /* JAL */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tJAL\t#%" PRId32, +- address, +- opcode, instruction->info.imm); +- } else { /* J */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tJ\t#%" PRId32, +- address, +- opcode, instruction->info.imm); +- } +- break; +- case 5: { /* JREG */ +- int32_t imm; +- nds32_parse_type_0(opcode, &imm); +- instruction->info.rb = (imm >> 10) & 0x1F; +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- switch (imm & 0x1F) { +- /* TODO */ +- case 0: /* JR */ +- if (imm & 0x20) { /* RET */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tRET\t$r%" PRIu8, +- address, +- opcode, instruction->info.rb); +- } else { /* JR */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tJR\t$r%" PRIu8, +- address, +- opcode, instruction->info.rb); +- } +- break; +- case 1: /* JRAL */ +- instruction->info.rt = (imm >> 20) & 0x1F; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tJRAL\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.rb); +- break; +- case 2: /* JRNEZ */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tJRNEZ\t$r%" PRIu8, +- address, +- opcode, instruction->info.rb); +- break; +- case 3: /* JRALNEZ */ +- instruction->info.rt = (imm >> 20) & 0x1F; +- if (instruction->info.rt == R30) +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tJRALNEZ\t$r%" PRIu8, +- address, +- opcode, instruction->info.rb); +- else +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tJRALNEZ\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, +- instruction->info.rt, +- instruction->info.rb); +- break; +- } +- } +- break; +- case 6: { /* BR1 */ +- int32_t imm; +- +- nds32_parse_type_0(opcode, &imm); +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- if ((imm >> 14) & 0x1) { /* BNE */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- /* sign-extend */ +- instruction->info.imm = (instruction->info.imm << 18) >> 18; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBNE\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } else { /* BEQ */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- /* sign-extend */ +- instruction->info.imm = (instruction->info.imm << 18) >> 18; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBEQ\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, +- instruction->info.ra, +- instruction->info.imm); +- } +- } +- break; +- case 7: { /* BR2 */ +- int32_t imm; +- +- nds32_parse_type_0(opcode, &imm); +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- switch ((imm >> 16) & 0xF) { +- case 2: /* BEQZ */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 16) >> 16; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBEQZ\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 3: /* BNEZ */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 16) >> 16; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBNEZ\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 4: /* BGEZ */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 16) >> 16; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBGEZ\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 5: /* BLTZ */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 16) >> 16; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBLTZ\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 6: /* BGTZ */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 16) >> 16; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBGTZ\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 7: /* BLEZ */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 16) >> 16; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBLEZ\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 12: /* BGEZAL */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 16) >> 16; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBGEZAL\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 13: /* BLTZAL */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 16) >> 16; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBLTZAL\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- } +- } +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_5_insn(struct nds32 *nds32, uint32_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- uint8_t opc_6; +- +- opc_6 = instruction->info.opc_6; +- +- switch (opc_6 & 0x7) { +- case 0: /* ADDI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tADDI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 1: /* SUBRI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSUBRI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 2: /* ANDI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tANDI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 3: /* XORI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tXORI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 4: /* ORI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tORI\t$r%" PRIu8 ",$r%" PRIu8 ",0x%8.8" PRIx32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 6: /* SLTI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSLTI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 7: /* SLTSI */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSLTSI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_6_insn(struct nds32 *nds32, uint32_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- uint8_t opc_6; +- +- opc_6 = instruction->info.opc_6; +- +- switch (opc_6 & 0x7) { +- case 2: { /* MISC */ +- int32_t imm; +- uint8_t sub_opc; +- +- nds32_parse_type_0(opcode, &imm); +- +- sub_opc = imm & 0x1F; +- switch (sub_opc) { +- case 0: /* STANDBY */ +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSTANDBY\t#%" PRIu32, +- address, +- opcode, (opcode >> 5) & 0x3); +- break; +- case 1: /* CCTL */ +- /* TODO */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCCTL", +- address, +- opcode); +- break; +- case 2: /* MFSR */ +- nds32_parse_type_1(opcode, &(instruction->info.rt), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_RESOURCE_ACCESS; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMFSR\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, +- (instruction->info.imm >> 10) & 0x3FF); +- break; +- case 3: /* MTSR */ +- nds32_parse_type_1(opcode, &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_RESOURCE_ACCESS; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMTSR\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.ra, +- (instruction->info.imm >> 10) & 0x3FF); +- break; +- case 4: /* IRET */ +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tIRET", +- address, +- opcode); +- break; +- case 5: /* TRAP */ +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tTRAP\t#%" PRId32, +- address, +- opcode, (imm >> 5) & 0x7FFF); +- break; +- case 6: /* TEQZ */ +- nds32_parse_type_1(opcode, &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tTEQZ\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.ra, +- (instruction->info.imm >> 5) & 0x7FFF); +- break; +- case 7: /* TNEZ */ +- nds32_parse_type_1(opcode, &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tTNEZ\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.ra, +- (instruction->info.imm >> 5) & 0x7FFF); +- break; +- case 8: /* DSB */ +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB", +- address, +- opcode); +- break; +- case 9: /* ISB */ +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISB", +- address, +- opcode); +- break; +- case 10: /* BREAK */ +- instruction->type = NDS32_INSN_MISC; +- instruction->info.sub_opc = imm & 0x1F; +- instruction->info.imm = (imm >> 5) & 0x7FFF; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tBREAK\t#%" PRId32, +- address, +- opcode, instruction->info.imm); +- break; +- case 11: /* SYSCALL */ +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tSYSCALL\t#%" PRId32, +- address, +- opcode, (imm >> 5) & 0x7FFF); +- break; +- case 12: /* MSYNC */ +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tMSYNC\t#%" PRId32, +- address, +- opcode, (imm >> 5) & 0x7); +- break; +- case 13: /* ISYNC */ +- nds32_parse_type_1(opcode, &(instruction->info.ra), +- &(instruction->info.imm)); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 +- "\tISYNC\t$r%" PRIu8, +- address, +- opcode, instruction->info.ra); +- break; +- case 14: /* TLBOP */ +- /* TODO */ +- nds32_parse_type_2(opcode, &(instruction->info.rt), +- &(instruction->info.ra), &(instruction->info.imm)); +- instruction->type = NDS32_INSN_RESOURCE_ACCESS; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tTLBOP", +- address, +- opcode); +- break; +- } +- +- break; +- } +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static uint32_t field_mask[9] = { +- 0x0, +- 0x1, +- 0x3, +- 0x7, +- 0xF, +- 0x1F, +- 0x3F, +- 0x7F, +- 0xFF, +-}; +- +-static uint8_t nds32_extract_field_8u(uint16_t opcode, uint32_t start, uint32_t length) +-{ +- if (length > 0 && length < 9) +- return (opcode >> start) & field_mask[length]; +- +- return 0; +-} +- +-static int nds32_parse_group_0_insn_16(struct nds32 *nds32, uint16_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- switch ((opcode >> 10) & 0x7) { +- case 0: /* MOV55 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5); +- instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tMOV55\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 1: /* MOVI55 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); +- instruction->info.imm = (instruction->info.imm << 27) >> 27; +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tMOVI55\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 2: /* ADD45, SUB45 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_DATA_PROC; +- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD45 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tADD45\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.rb); +- } else { /* SUB45 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSUB45\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.rb); +- } +- +- break; +- case 3: /* ADDI45, SUBI45 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_DATA_PROC; +- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI45 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tADDI45\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } else { /* SUBI45 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSUBI45\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } +- break; +- case 4: /* SRAI45, SRLI45 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_DATA_PROC; +- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SRAI45 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSRAI45\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } else { /* SRLI45 */ +- if ((instruction->info.rt == 0) && (instruction->info.imm == 0)) { +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 "\t\tNOP", +- address, +- opcode); +- } else { +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSRLI45\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } +- } +- break; +- case 5: +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->type = NDS32_INSN_DATA_PROC; +- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SLLI333 */ +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSLLI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } else { +- instruction->info.sub_opc = nds32_extract_field_8u(opcode, 0, 3); +- switch (instruction->info.sub_opc) { +- case 0: /* ZEB33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tZEB33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 1: /* ZEH33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tZEH33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 2: /* SEB33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSEB33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 3: /* SEH33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSEH33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 4: /* XLSB33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tXLSB33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 5: /* XLLB33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tXLLB33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 6: /* BMSKI33 */ +- instruction->info.ra = 0; +- instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3); +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tBMSKI33\t$r%" PRIu8 ",$r%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 7: /* FEXTI33 */ +- instruction->info.ra = 0; +- instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3); +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tFEXTI33\t$r%" PRIu8 ",$r%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 +- "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- } +- break; +- case 6: /* ADD333, SUB333 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 3); +- instruction->type = NDS32_INSN_DATA_PROC; +- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD333 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tADD333\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } else { /* SUB333 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSUB333\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.rb); +- } +- break; +- case 7: /* ADDI333, SUBI333 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); +- instruction->type = NDS32_INSN_DATA_PROC; +- if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI333 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tADDI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } else { /* SUBI333 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSUBI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- } +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_1_insn_16(struct nds32 *nds32, uint16_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- switch ((opcode >> 9) & 0xF) { +- case 0: /* LWI333 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tLWI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 1: /* LWI333.BI */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tLWI333.BI\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm << 2); +- break; +- case 2: /* LHI333 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1; +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tLHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 3: /* LBI333 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tLBI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 4: /* SWI333 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSWI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 5: /* SWI333.BI */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSWI333.BI\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 6: /* SHI333 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1; +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 2; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 7: /* SBI333 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 1; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", +- address, +- opcode, instruction->info.rt, instruction->info.ra, +- instruction->info.imm); +- break; +- case 8: /* ADDRI36.SP */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 6) << 2; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tADDRI36.SP\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 9: /* LWI45.FE */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); +- instruction->info.imm -= 32; +- instruction->info.imm <<= 2; +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, R8, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tLWI45.FE\t$r%" PRIu8 ",[#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 10: /* LWI450 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tLWI450\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 11: /* SWI450 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, instruction->info.ra, +- &(instruction->access_start)); +- instruction->access_end = instruction->access_start + 4; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSWI450\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 12: +- case 13: +- case 14: +- case 15: /* LWI37, SWI37 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2; +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, R28, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tLWI37\t$r%" PRIu8 ",[fp+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } else { /* SWI37 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSWI37\t$r%" PRIu8 ",[fp+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } +- break; +- default: /* ERROR */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_2_insn_16(struct nds32 *nds32, uint16_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- switch ((opcode >> 11) & 0x3) { +- case 0: /* BEQZ38 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); +- instruction->info.imm = (instruction->info.imm << 24) >> 24; +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tBEQZ38\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 1: /* BNEZ38 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); +- instruction->info.imm = (instruction->info.imm << 24) >> 24; +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tBNEZ38\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 2: /* BEQS38,J8 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); +- instruction->info.imm = (instruction->info.imm << 24) >> 24; +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- if (instruction->info.rt == 5) { /* J8 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tJ8\t#%" PRId32, +- address, +- opcode, instruction->info.imm); +- } else { /* BEQS38 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tBEQS38\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } +- break; +- case 3: /* BNES38, JR5, RET5, JRAL5 */ +- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); +- instruction->info.imm = (instruction->info.imm << 24) >> 24; +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- if (instruction->info.rt == 5) { +- instruction->info.imm = 0; +- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); +- switch (nds32_extract_field_8u(opcode, 5, 3)) { +- case 0: /* JR5 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tJR5\t$r%" PRIu8, +- address, +- opcode, instruction->info.rb); +- break; +- case 1: /* JRAL5 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tJRAL5\t$r%" PRIu8, +- address, +- opcode, instruction->info.rb); +- break; +- case 2: /* EX9.IT */ +- instruction->info.rb = 0; +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); +- /* TODO: implement real instruction semantics */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tEX9.IT\t#%" PRId32, +- address, +- opcode, instruction->info.imm); +- break; +- case 4: /* RET5 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tRET5\t$r%" PRIu8, +- address, +- opcode, instruction->info.rb); +- break; +- case 5: /* ADD5.PC */ +- instruction->info.rt = 0; +- instruction->info.rt = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tADD5.PC\t$r%" PRIu8, +- address, +- opcode, instruction->info.rt); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 +- "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- } else { /* BNES38 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tBNES38\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } +- break; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_parse_group_3_insn_16(struct nds32 *nds32, uint16_t opcode, +- uint32_t address, struct nds32_instruction *instruction) +-{ +- switch ((opcode >> 11) & 0x3) { +- case 0: +- switch ((opcode >> 9) & 0x3) { +- case 0: /* SLTS45 */ +- instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSLTS45\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.ra, instruction->info.rb); +- break; +- case 1: /* SLT45 */ +- instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSLT45\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.ra, instruction->info.rb); +- break; +- case 2: /* SLTSI45 */ +- instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSLTSI45\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.ra, instruction->info.imm); +- break; +- case 3: /* SLTI45 */ +- instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSLTI45\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.ra, instruction->info.imm); +- break; +- } +- break; +- case 1: +- switch ((opcode >> 9) & 0x3) { +- case 0: +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); +- instruction->info.imm = (instruction->info.imm << 24) >> 24; +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- if (nds32_extract_field_8u(opcode, 8, 1) == 0) { /* BEQZS8 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tBEQZS8\t#%" PRId32, +- address, +- opcode, instruction->info.imm); +- } else { /* BNEZS8 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tBNEZS8\t#%" PRId32, +- address, +- opcode, instruction->info.imm); +- } +- break; +- case 1: /* BREAK16 */ +- if (((opcode >> 5) & 0xF) == 0) { +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tBREAK16\t#%" PRId16, +- address, +- opcode, (int16_t)(opcode & 0x1F)); +- } else { /* EX9.IT */ +- instruction->type = NDS32_INSN_MISC; +- /* TODO: implement real instruction semantics */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tEX9.IT\t#%" PRId16, +- address, +- opcode, (int16_t)(opcode & 0x1FF)); +- } +- break; +- case 2: /* ADDI10S */ +- case 3: +- instruction->info.imm = opcode & 0x3FF; +- instruction->info.imm = (instruction->info.imm << 22) >> 22; +- instruction->type = NDS32_INSN_DATA_PROC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tADDI10.SP\t#%" PRId32, +- address, +- opcode, instruction->info.imm); +- break; +- } +- break; +- case 2: +- instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2; +- instruction->type = NDS32_INSN_LOAD_STORE; +- nds32_get_mapped_reg(nds32, R31, &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = instruction->access_start + 4; +- if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37.SP */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tLWI37.SP\t$r%" PRIu8 ",[+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } else { /* SWI37.SP */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tSWI37.SP\t$r%" PRIu8 ",[+#%" PRId32 "]", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- } +- break; +- case 3: +- switch ((opcode >> 9) & 0x3) { +- case 0: /* IFCALL9 */ +- instruction->info.imm = opcode & 0x1FF; +- instruction->type = NDS32_INSN_JUMP_BRANCH; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tIFCALL9\t#%" PRId32 "", +- address, +- opcode, instruction->info.imm); +- break; +- case 1: /* MOVPI45 */ +- instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5) + 16; +- instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tMOVPI45\t$r%" PRIu8 ",#%" PRId32 "", +- address, +- opcode, instruction->info.rt, instruction->info.imm); +- break; +- case 2: /* PUSH25, POP25, MOVD44 */ +- switch ((opcode >> 7) & 0x3) { +- case 0: /* PUSH25 */ +- { +- uint8_t re; +- uint8_t gpr_count; +- +- instruction->type = NDS32_INSN_LOAD_STORE; +- instruction->info.imm = +- nds32_extract_field_8u(opcode, 0, 5) << 3; +- re = nds32_extract_field_8u(opcode, 5, 2); +- +- if (re == 0) +- re = 6; +- else if (re == 1) +- re = 8; +- else if (re == 2) +- re = 10; +- else if (re == 3) +- re = 14; +- +- instruction->info.rd = re; +- /* GPRs list: R6 ~ Re and fp, gp, lp */ +- gpr_count = 3 + (re - 5); +- +- nds32_get_mapped_reg(nds32, R31, +- &(instruction->access_end)); +- instruction->access_start = +- instruction->access_end - (gpr_count * 4); +- +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tPUSH25\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rd, +- instruction->info.imm); +- } +- break; +- case 1: /* POP25 */ +- { +- uint8_t re; +- uint8_t gpr_count; +- +- instruction->type = NDS32_INSN_LOAD_STORE; +- instruction->info.imm = +- nds32_extract_field_8u(opcode, 0, 5) << 3; +- re = nds32_extract_field_8u(opcode, 5, 2); +- +- if (re == 0) +- re = 6; +- else if (re == 1) +- re = 8; +- else if (re == 2) +- re = 10; +- else if (re == 3) +- re = 14; +- +- instruction->info.rd = re; +- /* GPRs list: R6 ~ Re and fp, gp, lp */ +- gpr_count = 3 + (re - 5); +- +- nds32_get_mapped_reg(nds32, R31, +- &(instruction->access_start)); +- instruction->access_start += instruction->info.imm; +- instruction->access_end = +- instruction->access_start + (gpr_count * 4); +- +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tPOP25\t$r%" PRIu8 ",#%" PRId32, +- address, +- opcode, instruction->info.rd, +- instruction->info.imm); +- } +- break; +- case 2: /* MOVD44 */ +- case 3: +- instruction->info.ra = +- nds32_extract_field_8u(opcode, 0, 4) * 2; +- instruction->info.rt = +- nds32_extract_field_8u(opcode, 4, 4) * 2; +- instruction->type = NDS32_INSN_MISC; +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tMOVD44\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- } +- break; +- case 3: /* NEG33, NOT33, MUL33, XOR33, AND33, OR33 */ +- instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); +- instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); +- instruction->type = NDS32_INSN_DATA_PROC; +- switch (opcode & 0x7) { +- case 2: /* NEG33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tNEG33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 3: /* NOT33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tNOT33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 4: /* MUL33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tMUL33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 5: /* XOR33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tXOR33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 6: /* AND33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tAND33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- case 7: /* OR33 */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 +- "\t\tOR33\t$r%" PRIu8 ",$r%" PRIu8, +- address, +- opcode, instruction->info.rt, instruction->info.ra); +- break; +- } +- break; +- } +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction) +-{ +- int retval = ERROR_OK; +- +- /* clear fields, to avoid confusion */ +- memset(instruction, 0, sizeof(struct nds32_instruction)); +- +- if (opcode >> 31) { +- /* 16 bits instruction */ +- instruction->instruction_size = 2; +- opcode = (opcode >> 16) & 0xFFFF; +- instruction->opcode = opcode; +- +- switch ((opcode >> 13) & 0x3) { +- case 0: +- retval = nds32_parse_group_0_insn_16(nds32, opcode, address, instruction); +- break; +- case 1: +- retval = nds32_parse_group_1_insn_16(nds32, opcode, address, instruction); +- break; +- case 2: +- retval = nds32_parse_group_2_insn_16(nds32, opcode, address, instruction); +- break; +- case 3: +- retval = nds32_parse_group_3_insn_16(nds32, opcode, address, instruction); +- break; +- default: +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- } else { +- /* 32 bits instruction */ +- instruction->instruction_size = 4; +- instruction->opcode = opcode; +- +- uint8_t opc_6; +- opc_6 = opcode >> 25; +- instruction->info.opc_6 = opc_6; +- +- switch ((opc_6 >> 3) & 0x7) { +- case 0: /* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */ +- retval = nds32_parse_group_0_insn(nds32, opcode, address, instruction); +- break; +- case 1: /* SBI, SHI, SWI, SBI.bi, SHI.bi, SWI.bi */ +- retval = nds32_parse_group_1_insn(nds32, opcode, address, instruction); +- break; +- case 2: /* LBSI, LHSI, DPREFI, LBSI.bi, LHSI.bi, LBGP */ +- retval = nds32_parse_group_2_insn(nds32, opcode, address, instruction); +- break; +- case 3: /* MEM, LSMW, HWGP, SBGP */ +- retval = nds32_parse_group_3_insn(nds32, opcode, address, instruction); +- break; +- case 4: /* ALU_1, ALU_2, MOVI, SETHI, JI, JREG, BR1, BR2 */ +- retval = nds32_parse_group_4_insn(nds32, opcode, address, instruction); +- break; +- case 5: /* ADDI, SUBRI, ANDI, XORI, ORI, SLTI, SLTSI */ +- retval = nds32_parse_group_5_insn(nds32, opcode, address, instruction); +- break; +- case 6: /* MISC */ +- retval = nds32_parse_group_6_insn(nds32, opcode, address, instruction); +- break; +- default: /* ERROR */ +- snprintf(instruction->text, +- 128, +- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", +- address, +- opcode); +- return ERROR_FAIL; +- } +- } +- +- return retval; +-} +diff --git a/src/target/nds32_disassembler.h b/src/target/nds32_disassembler.h +deleted file mode 100644 +index f2c8e8596..000000000 +--- a/src/target/nds32_disassembler.h ++++ /dev/null +@@ -1,45 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_DISASSEMBLER_H +-#define OPENOCD_TARGET_NDS32_DISASSEMBLER_H +- +-#include +- +-enum nds32_instruction_type { +- NDS32_INSN_DATA_PROC = 0, +- NDS32_INSN_LOAD_STORE, +- NDS32_INSN_JUMP_BRANCH, +- NDS32_INSN_RESOURCE_ACCESS, +- NDS32_INSN_MISC, +-}; +- +-struct nds32_instruction { +- enum nds32_instruction_type type; +- char text[128]; +- uint32_t opcode; +- uint8_t instruction_size; +- uint32_t access_start; +- uint32_t access_end; +- +- struct { +- uint8_t opc_6; +- uint8_t rt; +- uint8_t ra; +- uint8_t rb; +- uint8_t rd; +- uint8_t sub_opc; +- int32_t imm; +- } info; +- +-}; +- +-int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value); +-int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address, +- struct nds32_instruction *instruction); +- +-#endif /* OPENOCD_TARGET_NDS32_DISASSEMBLER_H */ +diff --git a/src/target/nds32_edm.h b/src/target/nds32_edm.h +deleted file mode 100644 +index 3213604b9..000000000 +--- a/src/target/nds32_edm.h ++++ /dev/null +@@ -1,106 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_EDM_H +-#define OPENOCD_TARGET_NDS32_EDM_H +- +-#include "helper/types.h" +- +-/** +- * @file +- * This is the interface to the Embedded Debug Module for Andes cores. +- */ +- +-/* EDM misc registers */ +-enum nds_edm_misc_reg { +- NDS_EDM_MISC_DIMIR = 0x0, +- NDS_EDM_MISC_SBAR, +- NDS_EDM_MISC_EDM_CMDR, +- NDS_EDM_MISC_DBGER, +- NDS_EDM_MISC_ACC_CTL, +- NDS_EDM_MISC_EDM_PROBE, +- NDS_EDM_MISC_GEN_PORT0, +- NDS_EDM_MISC_GEN_PORT1, +-}; +- +-/* EDM system registers */ +-enum nds_edm_system_reg { +- NDS_EDM_SR_BPC0 = 0x00, +- NDS_EDM_SR_BPC1, +- NDS_EDM_SR_BPC2, +- NDS_EDM_SR_BPC3, +- NDS_EDM_SR_BPC4, +- NDS_EDM_SR_BPC5, +- NDS_EDM_SR_BPC6, +- NDS_EDM_SR_BPC7, +- NDS_EDM_SR_BPA0 = 0x08, +- NDS_EDM_SR_BPA1, +- NDS_EDM_SR_BPA2, +- NDS_EDM_SR_BPA3, +- NDS_EDM_SR_BPA4, +- NDS_EDM_SR_BPA5, +- NDS_EDM_SR_BPA6, +- NDS_EDM_SR_BPA7, +- NDS_EDM_SR_BPAM0 = 0x10, +- NDS_EDM_SR_BPAM1, +- NDS_EDM_SR_BPAM2, +- NDS_EDM_SR_BPAM3, +- NDS_EDM_SR_BPAM4, +- NDS_EDM_SR_BPAM5, +- NDS_EDM_SR_BPAM6, +- NDS_EDM_SR_BPAM7, +- NDS_EDM_SR_BPV0 = 0x18, +- NDS_EDM_SR_BPV1, +- NDS_EDM_SR_BPV2, +- NDS_EDM_SR_BPV3, +- NDS_EDM_SR_BPV4, +- NDS_EDM_SR_BPV5, +- NDS_EDM_SR_BPV6, +- NDS_EDM_SR_BPV7, +- NDS_EDM_SR_BPCID0 = 0x20, +- NDS_EDM_SR_BPCID1, +- NDS_EDM_SR_BPCID2, +- NDS_EDM_SR_BPCID3, +- NDS_EDM_SR_BPCID4, +- NDS_EDM_SR_BPCID5, +- NDS_EDM_SR_BPCID6, +- NDS_EDM_SR_BPCID7, +- NDS_EDM_SR_EDM_CFG = 0x28, +- NDS_EDM_SR_EDMSW = 0x30, +- NDS_EDM_SR_EDM_CTL = 0x38, +- NDS_EDM_SR_EDM_DTR = 0x40, +- NDS_EDM_SR_BPMTV = 0x48, +- NDS_EDM_SR_DIMBR = 0x50, +- NDS_EDM_SR_TECR0 = 0x70, +- NDS_EDM_SR_TECR1 = 0x71, +-}; +- +-enum nds_memory_access { +- NDS_MEMORY_ACC_BUS = 0, +- NDS_MEMORY_ACC_CPU, +-}; +- +-enum nds_memory_select { +- NDS_MEMORY_SELECT_AUTO = 0, +- NDS_MEMORY_SELECT_MEM = 1, +- NDS_MEMORY_SELECT_ILM = 2, +- NDS_MEMORY_SELECT_DLM = 3, +-}; +- +-#define NDS_DBGER_DEX (0x1) +-#define NDS_DBGER_DPED (0x2) +-#define NDS_DBGER_CRST (0x4) +-#define NDS_DBGER_AT_MAX (0x8) +-#define NDS_DBGER_ILL_SEC_ACC (0x10) +-#define NDS_DBGER_ALL_SUPRS_EX (0x40000000) +-#define NDS_DBGER_RESACC (0x80000000) +-#define NDS_DBGER_CLEAR_ALL (0x1F) +- +-#define NDS_EDMSW_WDV (1 << 0) +-#define NDS_EDMSW_RDV (1 << 1) +- +-#endif /* OPENOCD_TARGET_NDS32_EDM_H */ +diff --git a/src/target/nds32_insn.h b/src/target/nds32_insn.h +deleted file mode 100644 +index 25eb9ab8c..000000000 +--- a/src/target/nds32_insn.h ++++ /dev/null +@@ -1,67 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_INSN_H +-#define OPENOCD_TARGET_NDS32_INSN_H +- +-#define NOP (0x40000009) +-#define DSB (0x64000008) +-#define ISB (0x64000009) +-#define BEQ_MINUS_12 (0x4C000000 | 0x3FFA) +-#define MTSR_DTR(a) (0x64000003 | (((0x03 << 7) | (0x08 << 3) | (0x00 << 0)) << 10) | (((a) & 0x1F) << 20)) +-#define MFSR_DTR(a) (0x64000002 | (((0x03 << 7) | (0x08 << 3) | (0x00 << 0)) << 10) | (((a) & 0x1F) << 20)) +-#define SETHI(a, b) (0x46000000 | ((a) << 20) | (b)) +-#define ORI(a, b, c) (0x58000000 | ((a) << 20) | ((b) << 15) | (c)) +-#define LWI_BI(a, b) (0x0C000001 | (a << 20) | (b << 15)) +-#define LHI_BI(a, b) (0x0A000001 | (a << 20) | (b << 15)) +-#define LBI_BI(a, b) (0x08000001 | (a << 20) | (b << 15)) +-#define SWI_BI(a, b) (0x1C000001 | (a << 20) | (b << 15)) +-#define SHI_BI(a, b) (0x1A000001 | (a << 20) | (b << 15)) +-#define SBI_BI(a, b) (0x18000001 | (a << 20) | (b << 15)) +-#define IRET (0x64000004) +-#define L1D_IX_WB(a) (0x64000021 | ((a) << 15)) +-#define L1D_IX_INVAL(a) (0x64000001 | ((a) << 15)) +-#define L1D_VA_INVAL(a) (0x64000101 | ((a) << 15)) +-#define L1D_VA_WB(a) (0x64000121 | ((a) << 15)) +-#define L1D_IX_RTAG(a) (0x64000061 | ((a) << 15)) +-#define L1D_IX_RWD(a) (0x64000081 | ((a) << 15)) +-#define L1I_IX_INVAL(a) (0x64000201 | ((a) << 15)) +-#define L1I_VA_INVAL(a) (0x64000301 | ((a) << 15)) +-#define L1I_IX_RTAG(a) (0x64000261 | ((a) << 15)) +-#define L1I_IX_RWD(a) (0x64000281 | ((a) << 15)) +-#define L1I_VA_FILLCK(a) (0x64000361 | ((a) << 15)) +-#define ISYNC(a) (0x6400000d | ((a) << 20)) +-#define MSYNC_STORE (0x6400002c) +-#define MSYNC_ALL (0x6400000c) +-#define TLBOP_TARGET_READ(a) (0x6400000e | ((a) << 15)) +-#define TLBOP_TARGET_PROBE(a, b) (0x640000AE | ((a) << 20) | ((b) << 15)) +-#define MFCPD(a, b, c) (0x6A000041 | (a << 20) | (b << 8) | (c << 4)) +-#define MFCPW(a, b, c) (0x6A000001 | (a << 20) | (b << 8) | (c << 4)) +-#define MTCPD(a, b, c) (0x6A000049 | (a << 20) | (b << 8) | (c << 4)) +-#define MTCPW(a, b, c) (0x6A000009 | (a << 20) | (b << 8) | (c << 4)) +-#define MOVI_(a, b) (0x44000000 | (a << 20) | (b & 0xFFFFF)) +-#define MFUSR_G0(a, b) (0x42000020 | (a << 20) | (b << 15)) +-#define MTUSR_G0(a, b) (0x42000021 | (a << 20) | (b << 15)) +-#define MFSR(a, b) (0x64000002 | (b << 10) | (a << 20)) +-#define MTSR(a, b) (0x64000003 | (b << 10) | (a << 20)) +-#define AMFAR(a, b) (0x60300060 | (a << 15) | b) +-#define AMTAR(a, b) (0x60300040 | (a << 15) | b) +-#define AMFAR2(a, b) (0x60300260 | (a << 15) | b) +-#define AMTAR2(a, b) (0x60300240 | (a << 15) | b) +-#define FMFCSR (0x6A000701) +-#define FMTCSR (0x6A000709) +-#define FMFCFG (0x6A000301) +-#define FMFSR(a, b) (0x6A000001 | ((a) << 20) | ((b) << 15)) +-#define FMTSR(a, b) (0x6A000009 | ((a) << 20) | ((b) << 15)) +-#define FMFDR(a, b) (0x6A000041 | ((a) << 20) | ((b) << 15)) +-#define FMTDR(a, b) (0x6A000049 | ((a) << 20) | ((b) << 15)) +- +-/* break instructions */ +-#define NDS32_BREAK_16 (0x00EA) +-#define NDS32_BREAK_32 (0x0A000064) +- +-#endif /* OPENOCD_TARGET_NDS32_INSN_H */ +diff --git a/src/target/nds32_reg.c b/src/target/nds32_reg.c +deleted file mode 100644 +index 1687e69ce..000000000 +--- a/src/target/nds32_reg.c ++++ /dev/null +@@ -1,369 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include "nds32_reg.h" +- +-static bool nds32_reg_init_done; +-static struct nds32_reg_s nds32_regs[TOTAL_REG_NUM]; +-static const struct nds32_reg_exception_s nds32_ex_reg_values[] = { +- {IR0, 3, 0x3, 2}, +- {IR0, 3, 0x3, 3}, +- {IR1, 3, 0x3, 2}, +- {IR1, 3, 0x3, 3}, +- {IR2, 3, 0x3, 2}, +- {IR2, 3, 0x3, 3}, +- {MR3, 1, 0x7, 0}, +- {MR3, 1, 0x7, 4}, +- {MR3, 1, 0x7, 6}, +- {MR3, 8, 0x7, 3}, +- {0, 0, 0, 0}, +-}; +- +-static inline void nds32_reg_set(uint32_t number, const char *simple_mnemonic, +- const char *symbolic_mnemonic, uint32_t sr_index, +- enum nds32_reg_type_s type, uint8_t size) +-{ +- nds32_regs[number].simple_mnemonic = simple_mnemonic; +- nds32_regs[number].symbolic_mnemonic = symbolic_mnemonic; +- nds32_regs[number].sr_index = sr_index; +- nds32_regs[number].type = type; +- nds32_regs[number].size = size; +-} +- +-void nds32_reg_init(void) +-{ +- if (nds32_reg_init_done == true) +- return; +- +- nds32_reg_set(R0, "r0", "r0", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R1, "r1", "r1", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R2, "r2", "r2", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R3, "r3", "r3", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R4, "r4", "r4", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R5, "r5", "r5", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R6, "r6", "r6", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R7, "r7", "r7", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R8, "r8", "r8", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R9, "r9", "r9", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R10, "r10", "r10", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R11, "r11", "r11", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R12, "r12", "r12", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R13, "r13", "r13", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R14, "r14", "r14", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R15, "r15", "r15", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R16, "r16", "r16", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R17, "r17", "r17", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R18, "r18", "r18", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R19, "r19", "r19", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R20, "r20", "r20", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R21, "r21", "r21", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R22, "r22", "r22", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R23, "r23", "r23", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R24, "r24", "r24", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R25, "r25", "r25", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R26, "r26", "p0", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R27, "r27", "p1", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R28, "fp", "fp", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R29, "gp", "gp", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R30, "lp", "lp", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(R31, "sp", "sp", 0, NDS32_REG_TYPE_GPR, 32); +- nds32_reg_set(PC, "pc", "pc", 31, NDS32_REG_TYPE_SPR, 32); +- +- nds32_reg_set(D0LO, "d0lo", "d0lo", 0, NDS32_REG_TYPE_SPR, 32); +- nds32_reg_set(D0HI, "d0hi", "d0hi", 1, NDS32_REG_TYPE_SPR, 32); +- nds32_reg_set(D1LO, "d1lo", "d1lo", 2, NDS32_REG_TYPE_SPR, 32); +- nds32_reg_set(D1HI, "d1hi", "d1hi", 3, NDS32_REG_TYPE_SPR, 32); +- nds32_reg_set(ITB, "itb", "itb", 28, NDS32_REG_TYPE_SPR, 32); +- nds32_reg_set(IFC_LP, "ifc_lp", "ifc_lp", 29, NDS32_REG_TYPE_SPR, 32); +- +- nds32_reg_set(CR0, "cr0", "CPU_VER", SRIDX(0, 0, 0), NDS32_REG_TYPE_CR, 32); +- nds32_reg_set(CR1, "cr1", "ICM_CFG", SRIDX(0, 1, 0), NDS32_REG_TYPE_CR, 32); +- nds32_reg_set(CR2, "cr2", "DCM_CFG", SRIDX(0, 2, 0), NDS32_REG_TYPE_CR, 32); +- nds32_reg_set(CR3, "cr3", "MMU_CFG", SRIDX(0, 3, 0), NDS32_REG_TYPE_CR, 32); +- nds32_reg_set(CR4, "cr4", "MSC_CFG", SRIDX(0, 4, 0), NDS32_REG_TYPE_CR, 32); +- nds32_reg_set(CR5, "cr5", "CORE_ID", SRIDX(0, 0, 1), NDS32_REG_TYPE_CR, 32); +- nds32_reg_set(CR6, "cr6", "FUCOP_EXIST", SRIDX(0, 5, 0), NDS32_REG_TYPE_CR, 32); +- +- nds32_reg_set(IR0, "ir0", "PSW", SRIDX(1, 0, 0), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR1, "ir1", "IPSW", SRIDX(1, 0, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR2, "ir2", "P_IPSW", SRIDX(1, 0, 2), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR3, "ir3", "IVB", SRIDX(1, 1, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR4, "ir4", "EVA", SRIDX(1, 2, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR5, "ir5", "P_EVA", SRIDX(1, 2, 2), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR6, "ir6", "ITYPE", SRIDX(1, 3, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR7, "ir7", "P_ITYPE", SRIDX(1, 3, 2), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR8, "ir8", "MERR", SRIDX(1, 4, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR9, "ir9", "IPC", SRIDX(1, 5, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR10, "ir10", "P_IPC", SRIDX(1, 5, 2), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR11, "ir11", "OIPC", SRIDX(1, 5, 3), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR12, "ir12", "P_P0", SRIDX(1, 6, 2), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR13, "ir13", "P_P1", SRIDX(1, 7, 2), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR14, "ir14", "INT_MASK", SRIDX(1, 8, 0), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR15, "ir15", "INT_PEND", SRIDX(1, 9, 0), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR16, "ir16", "", SRIDX(1, 10, 0), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR17, "ir17", "", SRIDX(1, 10, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR18, "ir18", "", SRIDX(1, 11, 0), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR19, "ir19", "", SRIDX(1, 1, 2), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR20, "ir20", "", SRIDX(1, 10, 2), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR21, "ir21", "", SRIDX(1, 10, 3), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR22, "ir22", "", SRIDX(1, 10, 4), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR23, "ir23", "", SRIDX(1, 10, 5), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR24, "ir24", "", SRIDX(1, 10, 6), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR25, "ir25", "", SRIDX(1, 10, 7), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR26, "ir26", "", SRIDX(1, 8, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR27, "ir27", "", SRIDX(1, 9, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR28, "ir28", "", SRIDX(1, 11, 1), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR29, "ir29", "", SRIDX(1, 9, 4), NDS32_REG_TYPE_IR, 32); +- nds32_reg_set(IR30, "ir30", "", SRIDX(1, 1, 3), NDS32_REG_TYPE_IR, 32); +- +- nds32_reg_set(MR0, "mr0", "MMU_CTL", SRIDX(2, 0, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR1, "mr1", "L1_PPTB", SRIDX(2, 1, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR2, "mr2", "TLB_VPN", SRIDX(2, 2, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR3, "mr3", "TLB_DATA", SRIDX(2, 3, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR4, "mr4", "TLB_MISC", SRIDX(2, 4, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR5, "mr5", "VLPT_IDX", SRIDX(2, 5, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR6, "mr6", "ILMB", SRIDX(2, 6, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR7, "mr7", "DLMB", SRIDX(2, 7, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR8, "mr8", "CACHE_CTL", SRIDX(2, 8, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR9, "mr9", "HSMP_SADDR", SRIDX(2, 9, 0), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR10, "mr10", "HSMP_EADDR", SRIDX(2, 9, 1), NDS32_REG_TYPE_MR, 32); +- nds32_reg_set(MR11, "mr11", "", SRIDX(2, 0, 1), NDS32_REG_TYPE_MR, 32); +- +- nds32_reg_set(DR0, "dr0", "BPC0", SRIDX(3, 0, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR1, "dr1", "BPA0", SRIDX(3, 1, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR2, "dr2", "BPAM0", SRIDX(3, 2, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR3, "dr3", "BPV0", SRIDX(3, 3, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR4, "dr4", "BPCID0", SRIDX(3, 4, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR5, "dr5", "BPC1", SRIDX(3, 0, 1), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR6, "dr6", "BPA1", SRIDX(3, 1, 1), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR7, "dr7", "BPAM1", SRIDX(3, 2, 1), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR8, "dr8", "BPV1", SRIDX(3, 3, 1), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR9, "dr9", "BPCID1", SRIDX(3, 4, 1), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR10, "dr10", "BPC2", SRIDX(3, 0, 2), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR11, "dr11", "BPA2", SRIDX(3, 1, 2), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR12, "dr12", "BPAM2", SRIDX(3, 2, 2), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR13, "dr13", "BPV2", SRIDX(3, 3, 2), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR14, "dr14", "BPCID2", SRIDX(3, 4, 2), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR15, "dr15", "BPC3", SRIDX(3, 0, 3), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR16, "dr16", "BPA3", SRIDX(3, 1, 3), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR17, "dr17", "BPAM3", SRIDX(3, 2, 3), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR18, "dr18", "BPV3", SRIDX(3, 3, 3), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR19, "dr19", "BPCID3", SRIDX(3, 4, 3), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR20, "dr20", "BPC4", SRIDX(3, 0, 4), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR21, "dr21", "BPA4", SRIDX(3, 1, 4), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR22, "dr22", "BPAM4", SRIDX(3, 2, 4), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR23, "dr23", "BPV4", SRIDX(3, 3, 4), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR24, "dr24", "BPCID4", SRIDX(3, 4, 4), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR25, "dr25", "BPC5", SRIDX(3, 0, 5), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR26, "dr26", "BPA5", SRIDX(3, 1, 5), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR27, "dr27", "BPAM5", SRIDX(3, 2, 5), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR28, "dr28", "BPV5", SRIDX(3, 3, 5), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR29, "dr29", "BPCID5", SRIDX(3, 4, 5), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR30, "dr30", "BPC6", SRIDX(3, 0, 6), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR31, "dr31", "BPA6", SRIDX(3, 1, 6), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR32, "dr32", "BPAM6", SRIDX(3, 2, 6), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR33, "dr33", "BPV6", SRIDX(3, 3, 6), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR34, "dr34", "BPCID6", SRIDX(3, 4, 6), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR35, "dr35", "BPC7", SRIDX(3, 0, 7), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR36, "dr36", "BPA7", SRIDX(3, 1, 7), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR37, "dr37", "BPAM7", SRIDX(3, 2, 7), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR38, "dr38", "BPV7", SRIDX(3, 3, 7), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR39, "dr39", "BPCID7", SRIDX(3, 4, 7), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR40, "dr40", "EDM_CFG", SRIDX(3, 5, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR41, "dr41", "EDMSW", SRIDX(3, 6, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR42, "dr42", "EDM_CTL", SRIDX(3, 7, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR43, "dr43", "EDM_DTR", SRIDX(3, 8, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR44, "dr44", "BPMTC", SRIDX(3, 9, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR45, "dr45", "DIMBR", SRIDX(3, 10, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR46, "dr46", "TECR0", SRIDX(3, 14, 0), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR47, "dr47", "TECR1", SRIDX(3, 14, 1), NDS32_REG_TYPE_DR, 32); +- nds32_reg_set(DR48, "dr48", "", SRIDX(3, 11, 0), NDS32_REG_TYPE_DR, 32); +- +- nds32_reg_set(PFR0, "pfr0", "PFMC0", SRIDX(4, 0, 0), NDS32_REG_TYPE_PFR, 32); +- nds32_reg_set(PFR1, "pfr1", "PFMC1", SRIDX(4, 0, 1), NDS32_REG_TYPE_PFR, 32); +- nds32_reg_set(PFR2, "pfr2", "PFMC2", SRIDX(4, 0, 2), NDS32_REG_TYPE_PFR, 32); +- nds32_reg_set(PFR3, "pfr3", "PFM_CTL", SRIDX(4, 1, 0), NDS32_REG_TYPE_PFR, 32); +- +- nds32_reg_set(DMAR0, "dmar0", "DMA_CFG", SRIDX(5, 0, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR1, "dmar1", "DMA_GCSW", SRIDX(5, 1, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR2, "dmar2", "DMA_CHNSEL", SRIDX(5, 2, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR3, "dmar3", "DMA_ACT", SRIDX(5, 3, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR4, "dmar4", "DMA_SETUP", SRIDX(5, 4, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR5, "dmar5", "DMA_ISADDR", SRIDX(5, 5, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR6, "dmar6", "DMA_ESADDR", SRIDX(5, 6, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR7, "dmar7", "DMA_TCNT", SRIDX(5, 7, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR8, "dmar8", "DMA_STATUS", SRIDX(5, 8, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR9, "dmar9", "DMA_2DSET", SRIDX(5, 9, 0), NDS32_REG_TYPE_DMAR, 32); +- nds32_reg_set(DMAR10, "dmar10", "DMA_2DSCTL", SRIDX(5, 9, 1), NDS32_REG_TYPE_DMAR, 32); +- +- nds32_reg_set(RACR, "racr", "PRUSR_ACC_CTL", SRIDX(4, 4, 0), NDS32_REG_TYPE_RACR, 32); +- nds32_reg_set(FUCPR, "fucpr", "FUCOP_CTL", SRIDX(4, 5, 0), NDS32_REG_TYPE_RACR, 32); +- +- nds32_reg_set(IDR0, "idr0", "SDZ_CTL", SRIDX(2, 15, 0), NDS32_REG_TYPE_IDR, 32); +- nds32_reg_set(IDR1, "idr1", "MISC_CTL", SRIDX(2, 15, 1), NDS32_REG_TYPE_IDR, 32); +- +- nds32_reg_set(SECUR0, "secur0", "", SRIDX(6, 0, 0), NDS32_REG_TYPE_SECURE, 32); +- +- nds32_reg_set(D0L24, "D0L24", "D0L24", 0x10, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(D1L24, "D1L24", "D1L24", 0x11, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(I0, "I0", "I0", 0x0, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(I1, "I1", "I1", 0x1, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(I2, "I2", "I2", 0x2, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(I3, "I3", "I3", 0x3, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(I4, "I4", "I4", 0x4, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(I5, "I5", "I5", 0x5, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(I6, "I6", "I6", 0x6, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(I7, "I7", "I7", 0x7, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(M1, "M1", "M1", 0x9, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(M2, "M2", "M2", 0xA, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(M3, "M3", "M3", 0xB, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(M5, "M5", "M5", 0xD, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(M6, "M6", "M6", 0xE, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(M7, "M7", "M7", 0xF, NDS32_REG_TYPE_AUMR, 32); +- +- nds32_reg_set(MOD, "MOD", "MOD", 0x8, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(LBE, "LBE", "LBE", 0x18, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(LE, "LE", "LE", 0x19, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(LC, "LC", "LC", 0x1A, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(ADM_VBASE, "ADM_VBASE", "ADM_VBASE", 0x1B, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(SHFT_CTL0, "SHFT_CTL0", "SHFT_CTL0", 0x12, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(SHFT_CTL1, "SHFT_CTL1", "SHFT_CTL1", 0x13, NDS32_REG_TYPE_AUMR, 32); +- +- nds32_reg_set(CB_CTL, "CB_CTL", "CB_CTL", 0x1F, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(CBB0, "CBB0", "CBB0", 0x0, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(CBB1, "CBB1", "CBB1", 0x1, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(CBB2, "CBB2", "CBB2", 0x2, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(CBB3, "CBB3", "CBB3", 0x3, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(CBE0, "CBE0", "CBE0", 0x4, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(CBE1, "CBE1", "CBE1", 0x5, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(CBE2, "CBE2", "CBE2", 0x6, NDS32_REG_TYPE_AUMR, 32); +- nds32_reg_set(CBE3, "CBE3", "CBE3", 0x7, NDS32_REG_TYPE_AUMR, 32); +- +- nds32_reg_set(FPCSR, "fpcsr", "FPCSR", 0x7, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FPCFG, "fpcfg", "FPCFG", 0x7, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS0, "fs0", "FS0", 0, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS1, "fs1", "FS1", 1, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS2, "fs2", "FS2", 2, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS3, "fs3", "FS3", 3, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS4, "fs4", "FS4", 4, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS5, "fs5", "FS5", 5, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS6, "fs6", "FS6", 6, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS7, "fs7", "FS7", 7, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS8, "fs8", "FS8", 8, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS9, "fs9", "FS9", 9, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS10, "fs10", "FS10", 10, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS11, "fs11", "FS11", 11, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS12, "fs12", "FS12", 12, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS13, "fs13", "FS13", 13, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS14, "fs14", "FS14", 14, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS15, "fs15", "FS15", 15, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS16, "fs16", "FS16", 16, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS17, "fs17", "FS17", 17, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS18, "fs18", "FS18", 18, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS19, "fs19", "FS19", 19, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS20, "fs20", "FS20", 20, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS21, "fs21", "FS21", 21, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS22, "fs22", "FS22", 22, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS23, "fs23", "FS23", 23, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS24, "fs24", "FS24", 24, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS25, "fs25", "FS25", 25, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS26, "fs26", "FS26", 26, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS27, "fs27", "FS27", 27, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS28, "fs28", "FS28", 28, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS29, "fs29", "FS29", 29, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS30, "fs30", "FS30", 30, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FS31, "fs31", "FS31", 31, NDS32_REG_TYPE_FPU, 32); +- nds32_reg_set(FD0, "fd0", "FD0", 0, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD1, "fd1", "FD1", 1, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD2, "fd2", "FD2", 2, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD3, "fd3", "FD3", 3, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD4, "fd4", "FD4", 4, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD5, "fd5", "FD5", 5, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD6, "fd6", "FD6", 6, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD7, "fd7", "FD7", 7, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD8, "fd8", "FD8", 8, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD9, "fd9", "FD9", 9, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD10, "fd10", "FD10", 10, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD11, "fd11", "FD11", 11, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD12, "fd12", "FD12", 12, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD13, "fd13", "FD13", 13, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD14, "fd14", "FD14", 14, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD15, "fd15", "FD15", 15, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD16, "fd16", "FD16", 16, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD17, "fd17", "FD17", 17, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD18, "fd18", "FD18", 18, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD19, "fd19", "FD19", 19, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD20, "fd20", "FD20", 20, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD21, "fd21", "FD21", 21, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD22, "fd22", "FD22", 22, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD23, "fd23", "FD23", 23, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD24, "fd24", "FD24", 24, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD25, "fd25", "FD25", 25, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD26, "fd26", "FD26", 26, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD27, "fd27", "FD27", 27, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD28, "fd28", "FD28", 28, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD29, "fd29", "FD29", 29, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD30, "fd30", "FD30", 30, NDS32_REG_TYPE_FPU, 64); +- nds32_reg_set(FD31, "fd31", "FD31", 31, NDS32_REG_TYPE_FPU, 64); +- +- nds32_reg_init_done = true; +-} +- +-uint32_t nds32_reg_sr_index(uint32_t number) +-{ +- return nds32_regs[number].sr_index; +-} +- +-enum nds32_reg_type_s nds32_reg_type(uint32_t number) +-{ +- return nds32_regs[number].type; +-} +- +-uint8_t nds32_reg_size(uint32_t number) +-{ +- return nds32_regs[number].size; +-} +- +-const char *nds32_reg_simple_name(uint32_t number) +-{ +- return nds32_regs[number].simple_mnemonic; +-} +- +-const char *nds32_reg_symbolic_name(uint32_t number) +-{ +- return nds32_regs[number].symbolic_mnemonic; +-} +- +-bool nds32_reg_exception(uint32_t number, uint32_t value) +-{ +- int i; +- const struct nds32_reg_exception_s *ex_reg_value; +- uint32_t field_value; +- +- i = 0; +- while (nds32_ex_reg_values[i].reg_num != 0) { +- ex_reg_value = nds32_ex_reg_values + i; +- +- if (ex_reg_value->reg_num == number) { +- field_value = (value >> ex_reg_value->ex_value_bit_pos) & +- ex_reg_value->ex_value_mask; +- if (field_value == ex_reg_value->ex_value) { +- LOG_WARNING("It will generate exceptions as setting %" PRIu32 " to %s", +- value, nds32_regs[number].simple_mnemonic); +- return true; +- } +- } +- +- i++; +- } +- +- return false; +-} +diff --git a/src/target/nds32_reg.h b/src/target/nds32_reg.h +deleted file mode 100644 +index 30cd24172..000000000 +--- a/src/target/nds32_reg.h ++++ /dev/null +@@ -1,314 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_REG_H +-#define OPENOCD_TARGET_NDS32_REG_H +- +-#define SRIDX(a, b, c) ((a << 7) | (b << 3) | c) +-#define NDS32_REGISTER_DISABLE (0x0) +- +-enum nds32_reg_number_s { +- R0 = 0, /* general registers */ +- R1, +- R2, +- R3, +- R4, +- R5, +- R6, +- R7, +- R8, +- R9, +- R10, +- R11, +- R12, +- R13, +- R14, +- R15, +- R16, +- R17, +- R18, +- R19, +- R20, +- R21, +- R22, +- R23, +- R24, +- R25, +- R26, +- R27, +- R28, +- R29, +- R30, +- R31, +- PC, +- D0LO, +- D0HI, +- D1LO, +- D1HI, +- ITB, +- IFC_LP, +- CR0, /* system registers */ +- CR1, +- CR2, +- CR3, +- CR4, +- CR5, +- CR6, +- IR0, +- IR1, +- IR2, +- IR3, +- IR4, +- IR5, +- IR6, +- IR7, +- IR8, +- IR9, +- IR10, +- IR11, +- IR12, +- IR13, +- IR14, +- IR15, +- IR16, +- IR17, +- IR18, +- IR19, +- IR20, +- IR21, +- IR22, +- IR23, +- IR24, +- IR25, +- IR26, +- IR27, +- IR28, +- IR29, +- IR30, +- MR0, +- MR1, +- MR2, +- MR3, +- MR4, +- MR5, +- MR6, +- MR7, +- MR8, +- MR9, +- MR10, +- MR11, +- DR0, +- DR1, +- DR2, +- DR3, +- DR4, +- DR5, +- DR6, +- DR7, +- DR8, +- DR9, +- DR10, +- DR11, +- DR12, +- DR13, +- DR14, +- DR15, +- DR16, +- DR17, +- DR18, +- DR19, +- DR20, +- DR21, +- DR22, +- DR23, +- DR24, +- DR25, +- DR26, +- DR27, +- DR28, +- DR29, +- DR30, +- DR31, +- DR32, +- DR33, +- DR34, +- DR35, +- DR36, +- DR37, +- DR38, +- DR39, +- DR40, +- DR41, +- DR42, +- DR43, +- DR44, +- DR45, +- DR46, +- DR47, +- DR48, +- PFR0, +- PFR1, +- PFR2, +- PFR3, +- DMAR0, +- DMAR1, +- DMAR2, +- DMAR3, +- DMAR4, +- DMAR5, +- DMAR6, +- DMAR7, +- DMAR8, +- DMAR9, +- DMAR10, +- RACR, +- FUCPR, +- IDR0, +- IDR1, +- SECUR0, +- D0L24, /* audio registers */ +- D1L24, +- I0, +- I1, +- I2, +- I3, +- I4, +- I5, +- I6, +- I7, +- M1, +- M2, +- M3, +- M5, +- M6, +- M7, +- MOD, +- LBE, +- LE, +- LC, +- ADM_VBASE, +- SHFT_CTL0, +- SHFT_CTL1, +- CB_CTL, +- CBB0, +- CBB1, +- CBB2, +- CBB3, +- CBE0, +- CBE1, +- CBE2, +- CBE3, +- FPCSR, /* fpu */ +- FPCFG, +- FS0, +- FS1, +- FS2, +- FS3, +- FS4, +- FS5, +- FS6, +- FS7, +- FS8, +- FS9, +- FS10, +- FS11, +- FS12, +- FS13, +- FS14, +- FS15, +- FS16, +- FS17, +- FS18, +- FS19, +- FS20, +- FS21, +- FS22, +- FS23, +- FS24, +- FS25, +- FS26, +- FS27, +- FS28, +- FS29, +- FS30, +- FS31, +- FD0, +- FD1, +- FD2, +- FD3, +- FD4, +- FD5, +- FD6, +- FD7, +- FD8, +- FD9, +- FD10, +- FD11, +- FD12, +- FD13, +- FD14, +- FD15, +- FD16, +- FD17, +- FD18, +- FD19, +- FD20, +- FD21, +- FD22, +- FD23, +- FD24, +- FD25, +- FD26, +- FD27, +- FD28, +- FD29, +- FD30, +- FD31, +- +- TOTAL_REG_NUM, +-}; +- +-enum nds32_reg_type_s { +- NDS32_REG_TYPE_GPR = 0, +- NDS32_REG_TYPE_SPR, +- NDS32_REG_TYPE_CR, +- NDS32_REG_TYPE_IR, +- NDS32_REG_TYPE_MR, +- NDS32_REG_TYPE_DR, +- NDS32_REG_TYPE_PFR, +- NDS32_REG_TYPE_DMAR, +- NDS32_REG_TYPE_RACR, +- NDS32_REG_TYPE_IDR, +- NDS32_REG_TYPE_AUMR, +- NDS32_REG_TYPE_SECURE, +- NDS32_REG_TYPE_FPU, +-}; +- +-struct nds32_reg_s { +- const char *simple_mnemonic; +- const char *symbolic_mnemonic; +- uint32_t sr_index; +- enum nds32_reg_type_s type; +- uint8_t size; +-}; +- +-struct nds32_reg_exception_s { +- uint32_t reg_num; +- uint32_t ex_value_bit_pos; +- uint32_t ex_value_mask; +- uint32_t ex_value; +-}; +- +-void nds32_reg_init(void); +-uint32_t nds32_reg_sr_index(uint32_t number); +-enum nds32_reg_type_s nds32_reg_type(uint32_t number); +-uint8_t nds32_reg_size(uint32_t number); +-const char *nds32_reg_simple_name(uint32_t number); +-const char *nds32_reg_symbolic_name(uint32_t number); +-bool nds32_reg_exception(uint32_t number, uint32_t value); +- +-#endif /* OPENOCD_TARGET_NDS32_REG_H */ +diff --git a/src/target/nds32_tlb.c b/src/target/nds32_tlb.c +deleted file mode 100644 +index a533e593d..000000000 +--- a/src/target/nds32_tlb.c ++++ /dev/null +@@ -1,67 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include "nds32_aice.h" +-#include "nds32_tlb.h" +- +-int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address, +- target_addr_t *physical_address) +-{ +- struct target *target = nds32->target; +- struct aice_port_s *aice = target_to_aice(target); +- +- return aice_read_tlb(aice, virtual_address, physical_address); +-} +- +-static struct page_table_walker_info_s page_table_info[PAGE_SIZE_NUM] = { +- /* 4K page */ +- {0xFFC00000, 20, 0x003FF000, 10, 0x00000FFF, 0xFFFFF000, 0xFFFFF000, 0xFFFFF000}, +- /* 8K page */ +- {0xFF000000, 22, 0x00FFE000, 11, 0x00001FFF, 0xFFFFF000, 0xFFFFE000, 0xFFFFE000}, +-}; +- +-int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address, +- target_addr_t *physical_address) +-{ +- struct target *target = nds32->target; +- uint32_t value_mr1; +- uint32_t load_address; +- uint32_t l1_page_table_entry; +- uint32_t l2_page_table_entry; +- uint32_t page_size_index = nds32->mmu_config.default_min_page_size; +- struct page_table_walker_info_s *page_table_info_p = +- &(page_table_info[page_size_index]); +- +- /* Read L1 Physical Page Table */ +- nds32_get_mapped_reg(nds32, MR1, &value_mr1); +- load_address = (value_mr1 & page_table_info_p->l1_base_mask) | +- ((virtual_address & page_table_info_p->l1_offset_mask) >> +- page_table_info_p->l1_offset_shift); +- /* load_address is physical address */ +- nds32_read_buffer(target, load_address, 4, (uint8_t *)&l1_page_table_entry); +- +- /* Read L2 Physical Page Table */ +- if (l1_page_table_entry & 0x1) /* L1_PTE not present */ +- return ERROR_FAIL; +- +- load_address = (l1_page_table_entry & page_table_info_p->l2_base_mask) | +- ((virtual_address & page_table_info_p->l2_offset_mask) >> +- page_table_info_p->l2_offset_shift); +- /* load_address is physical address */ +- nds32_read_buffer(target, load_address, 4, (uint8_t *)&l2_page_table_entry); +- +- if ((l2_page_table_entry & 0x1) != 0x1) /* L2_PTE not valid */ +- return ERROR_FAIL; +- +- *physical_address = (l2_page_table_entry & page_table_info_p->ppn_mask) | +- (virtual_address & page_table_info_p->va_offset_mask); +- +- return ERROR_OK; +-} +diff --git a/src/target/nds32_tlb.h b/src/target/nds32_tlb.h +deleted file mode 100644 +index 1edff294f..000000000 +--- a/src/target/nds32_tlb.h ++++ /dev/null +@@ -1,36 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_TLB_H +-#define OPENOCD_TARGET_NDS32_TLB_H +- +-#include "nds32.h" +- +-enum { +- PAGE_SIZE_4K = 0, +- PAGE_SIZE_8K, +- PAGE_SIZE_NUM, +-}; +- +-struct page_table_walker_info_s { +- +- uint32_t l1_offset_mask; +- uint32_t l1_offset_shift; +- uint32_t l2_offset_mask; +- uint32_t l2_offset_shift; +- uint32_t va_offset_mask; +- uint32_t l1_base_mask; +- uint32_t l2_base_mask; +- uint32_t ppn_mask; +-}; +- +-extern int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address, +- target_addr_t *physical_address); +-extern int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address, +- target_addr_t *physical_address); +- +-#endif /* OPENOCD_TARGET_NDS32_TLB_H */ +diff --git a/src/target/nds32_v2.c b/src/target/nds32_v2.c +deleted file mode 100644 +index 214929117..000000000 +--- a/src/target/nds32_v2.c ++++ /dev/null +@@ -1,774 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include +-#include +-#include "breakpoints.h" +-#include "nds32_insn.h" +-#include "nds32_reg.h" +-#include "nds32_edm.h" +-#include "nds32_cmd.h" +-#include "nds32_v2.h" +-#include "nds32_aice.h" +-#include "target_type.h" +- +-static int nds32_v2_register_mapping(struct nds32 *nds32, int reg_no) +-{ +- uint32_t max_level = nds32->max_interrupt_level; +- uint32_t cur_level = nds32->current_interrupt_level; +- +- if ((cur_level >= 1) && (cur_level < max_level)) { +- if (reg_no == IR0) { +- LOG_DEBUG("Map PSW to IPSW"); +- return IR1; +- } else if (reg_no == PC) { +- LOG_DEBUG("Map PC to IPC"); +- return IR9; +- } +- } else if ((cur_level >= 2) && (cur_level < max_level)) { +- if (reg_no == R26) { +- LOG_DEBUG("Mapping P0 to P_P0"); +- return IR12; +- } else if (reg_no == R27) { +- LOG_DEBUG("Mapping P1 to P_P1"); +- return IR13; +- } else if (reg_no == IR1) { +- LOG_DEBUG("Mapping IPSW to P_IPSW"); +- return IR2; +- } else if (reg_no == IR4) { +- LOG_DEBUG("Mapping EVA to P_EVA"); +- return IR5; +- } else if (reg_no == IR6) { +- LOG_DEBUG("Mapping ITYPE to P_ITYPE"); +- return IR7; +- } else if (reg_no == IR9) { +- LOG_DEBUG("Mapping IPC to P_IPC"); +- return IR10; +- } +- } else if (cur_level == max_level) { +- if (reg_no == PC) { +- LOG_DEBUG("Mapping PC to O_IPC"); +- return IR11; +- } +- } +- +- return reg_no; +-} +- +-static int nds32_v2_get_debug_reason(struct nds32 *nds32, uint32_t *reason) +-{ +- uint32_t val_itype; +- struct aice_port_s *aice = target_to_aice(nds32->target); +- +- aice_read_register(aice, IR6, &val_itype); +- +- *reason = val_itype & 0x0F; +- +- return ERROR_OK; +-} +- +-static int nds32_v2_activate_hardware_breakpoint(struct target *target) +-{ +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct breakpoint *bp; +- int32_t hbr_index = 0; +- +- for (bp = target->breakpoints; bp; bp = bp->next) { +- if (bp->type == BKPT_SOFT) { +- /* already set at nds32_v2_add_breakpoint() */ +- continue; +- } else if (bp->type == BKPT_HARD) { +- /* set address */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address); +- /* set mask */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0); +- /* set value */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0); +- +- if (nds32_v2->nds32.memory.address_translation) +- /* enable breakpoint (virtual address) */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2); +- else +- /* enable breakpoint (physical address) */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA); +- +- LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index, +- bp->address); +- +- hbr_index++; +- } else { +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v2_deactivate_hardware_breakpoint(struct target *target) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct breakpoint *bp; +- int32_t hbr_index = 0; +- +- for (bp = target->breakpoints; bp; bp = bp->next) { +- if (bp->type == BKPT_SOFT) +- continue; +- else if (bp->type == BKPT_HARD) +- /* disable breakpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0); +- else +- return ERROR_FAIL; +- +- LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index, +- bp->address); +- +- hbr_index++; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v2_activate_hardware_watchpoint(struct target *target) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); +- struct watchpoint *wp; +- int32_t wp_num = nds32_v2->next_hbr_index; +- uint32_t wp_config = 0; +- +- for (wp = target->watchpoints; wp; wp = wp->next) { +- +- wp_num--; +- wp->mask = wp->length - 1; +- if ((wp->address % wp->length) != 0) +- wp->mask = (wp->mask << 1) + 1; +- +- if (wp->rw == WPT_READ) +- wp_config = 0x3; +- else if (wp->rw == WPT_WRITE) +- wp_config = 0x5; +- else if (wp->rw == WPT_ACCESS) +- wp_config = 0x7; +- +- /* set/unset physical address bit of BPCn according to PSW.DT */ +- if (nds32_v2->nds32.memory.address_translation == false) +- wp_config |= 0x8; +- +- /* set address */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, +- wp->address - (wp->address % wp->length)); +- /* set mask */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); +- /* enable watchpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); +- /* set value */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0); +- +- LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, wp_num, +- wp->address, wp->mask); +- +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v2_deactivate_hardware_watchpoint(struct target *target) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); +- int32_t wp_num = nds32_v2->next_hbr_index; +- struct watchpoint *wp; +- +- for (wp = target->watchpoints; wp; wp = wp->next) { +- wp_num--; +- /* disable watchpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); +- +- LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, +- wp_num, wp->address, wp->mask); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v2_check_interrupt_stack(struct nds32_v2_common *nds32_v2) +-{ +- struct nds32 *nds32 = &(nds32_v2->nds32); +- struct aice_port_s *aice = target_to_aice(nds32->target); +- uint32_t val_ir0; +- uint32_t val_ir1; +- uint32_t val_ir2; +- uint32_t modified_psw; +- +- /* Save interrupt level */ +- aice_read_register(aice, IR0, &val_ir0); /* get $IR0 directly */ +- +- /* backup $IR0 */ +- nds32_v2->backup_ir0 = val_ir0; +- +- nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; +- +- if (nds32_reach_max_interrupt_level(nds32)) { +- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", +- nds32->current_interrupt_level); +- +- /* decrease interrupt level */ +- modified_psw = val_ir0 - 0x2; +- +- /* disable GIE, IT, DT, HSS */ +- modified_psw &= (~0x8C1); +- +- aice_write_register(aice, IR0, modified_psw); +- +- return ERROR_OK; +- } +- +- /* There is a case that single step also trigger another interrupt, +- then HSS bit in psw(ir0) will push to ipsw(ir1). +- Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2 +- Therefore, HSS bit in p_ipsw(ir2) also need clear. +- +- Only update $ir2 as current interrupt level is 2, because $ir2 will be random +- value if the target never reaches interrupt level 2. */ +- if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) { +- aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */ +- val_ir2 &= ~(0x01 << 11); +- aice_write_register(aice, IR2, val_ir2); +- } +- +- /* get original DT bit and set to current state let debugger has same memory view +- PSW.IT MUST be turned off. Otherwise, DIM could not operate normally. */ +- aice_read_register(aice, IR1, &val_ir1); +- modified_psw = val_ir0 | (val_ir1 & 0x80); +- aice_write_register(aice, IR0, modified_psw); +- +- return ERROR_OK; +-} +- +-static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2) +-{ +- struct nds32 *nds32 = &(nds32_v2->nds32); +- struct aice_port_s *aice = target_to_aice(nds32->target); +- +- /* restore origin $IR0 */ +- aice_write_register(aice, IR0, nds32_v2->backup_ir0); +- +- return ERROR_OK; +-} +- +-/** +- * Save processor state. This is called after a HALT instruction +- * succeeds, and on other occasions the processor enters debug mode +- * (breakpoint, watchpoint, etc). +- */ +-static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint) +-{ +- LOG_DEBUG("nds32_v2_debug_entry"); +- +- if (nds32->virtual_hosting) +- LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported " +- "under V1/V2 architecture. -->"); +- +- enum target_state backup_state = nds32->target->state; +- nds32->target->state = TARGET_HALTED; +- +- if (nds32->init_arch_info_after_halted == false) { +- /* init architecture info according to config registers */ +- CHECK_RETVAL(nds32_config(nds32)); +- +- nds32->init_arch_info_after_halted = true; +- } +- +- /* REVISIT entire cache should already be invalid !!! */ +- register_cache_invalidate(nds32->core_cache); +- +- /* deactivate all hardware breakpoints */ +- CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target)); +- +- if (enable_watchpoint) +- CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target)); +- +- if (nds32_examine_debug_reason(nds32) != ERROR_OK) { +- nds32->target->state = backup_state; +- +- /* re-activate all hardware breakpoints & watchpoints */ +- CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target)); +- +- if (enable_watchpoint) { +- /* activate all watchpoints */ +- CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target)); +- } +- +- return ERROR_FAIL; +- } +- +- /* check interrupt level before .full_context(), because +- * get_mapped_reg() in nds32_full_context() needs current_interrupt_level +- * information */ +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target); +- nds32_v2_check_interrupt_stack(nds32_v2); +- +- /* Save registers. */ +- nds32_full_context(nds32); +- +- return ERROR_OK; +-} +- +-/* target request support */ +-static int nds32_v2_target_request_data(struct target *target, +- uint32_t size, uint8_t *buffer) +-{ +- /* AndesCore could use DTR register to communicate with OpenOCD +- * to output messages +- * Target data will be put in buffer +- * The format of DTR is as follow +- * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd +- * target_req_cmd has three possible values: +- * TARGET_REQ_TRACEMSG +- * TARGET_REQ_DEBUGMSG +- * TARGET_REQ_DEBUGCHAR +- * if size == 0, target will call target_asciimsg(), +- * else call target_hexmsg() +- */ +- LOG_WARNING("Not implemented: %s", __func__); +- +- return ERROR_OK; +-} +- +-/** +- * Restore processor state. +- */ +-static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint) +-{ +- LOG_DEBUG("nds32_v2_leave_debug_state"); +- +- struct target *target = nds32->target; +- +- /* activate all hardware breakpoints */ +- CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target)); +- +- if (enable_watchpoint) { +- /* activate all watchpoints */ +- CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target)); +- } +- +- /* restore interrupt stack */ +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target); +- nds32_v2_restore_interrupt_stack(nds32_v2); +- +- /* restore PSW, PC, and R0 ... after flushing any modified +- * registers. +- */ +- CHECK_RETVAL(nds32_restore_context(target)); +- +- register_cache_invalidate(nds32->core_cache); +- +- return ERROR_OK; +-} +- +-static int nds32_v2_deassert_reset(struct target *target) +-{ +- int retval; +- +- CHECK_RETVAL(nds32_poll(target)); +- +- if (target->state != TARGET_HALTED) { +- /* reset only */ +- LOG_WARNING("%s: ran after reset and before halt ...", +- target_name(target)); +- retval = target_halt(target); +- if (retval != ERROR_OK) +- return retval; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v2_checksum_memory(struct target *target, +- target_addr_t address, uint32_t count, uint32_t *checksum) +-{ +- LOG_WARNING("Not implemented: %s", __func__); +- +- return ERROR_FAIL; +-} +- +-static int nds32_v2_add_breakpoint(struct target *target, +- struct breakpoint *breakpoint) +-{ +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); +- struct nds32 *nds32 = &(nds32_v2->nds32); +- int result; +- +- if (breakpoint->type == BKPT_HARD) { +- /* check hardware resource */ +- if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) { +- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " +- "breakpoints/watchpoints! The limit of " +- "combined hardware breakpoints/watchpoints " +- "is %" PRId32 ". -->", nds32_v2->n_hbr); +- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; +- } +- +- /* update next place to put hardware breakpoint */ +- nds32_v2->next_hbr_index++; +- +- /* hardware breakpoint insertion occurs before 'continue' actually */ +- return ERROR_OK; +- } else if (breakpoint->type == BKPT_SOFT) { +- result = nds32_add_software_breakpoint(target, breakpoint); +- if (result != ERROR_OK) { +- /* auto convert to hardware breakpoint if failed */ +- if (nds32->auto_convert_hw_bp) { +- /* convert to hardware breakpoint */ +- breakpoint->type = BKPT_HARD; +- +- return nds32_v2_add_breakpoint(target, breakpoint); +- } +- } +- +- return result; +- } else /* unrecognized breakpoint type */ +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int nds32_v2_remove_breakpoint(struct target *target, +- struct breakpoint *breakpoint) +-{ +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); +- +- if (breakpoint->type == BKPT_HARD) { +- if (nds32_v2->next_hbr_index <= 0) +- return ERROR_FAIL; +- +- /* update next place to put hardware breakpoint */ +- nds32_v2->next_hbr_index--; +- +- /* hardware breakpoint removal occurs after 'halted' actually */ +- return ERROR_OK; +- } else if (breakpoint->type == BKPT_SOFT) { +- return nds32_remove_software_breakpoint(target, breakpoint); +- } else /* unrecognized breakpoint type */ +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int nds32_v2_add_watchpoint(struct target *target, +- struct watchpoint *watchpoint) +-{ +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); +- +- /* check hardware resource */ +- if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) { +- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " +- "breakpoints/watchpoints! The limit of " +- "combined hardware breakpoints/watchpoints is %" PRId32 ". -->", nds32_v2->n_hbr); +- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; +- } +- +- /* update next place to put hardware watchpoint */ +- nds32_v2->next_hbr_index++; +- +- return ERROR_OK; +-} +- +-static int nds32_v2_remove_watchpoint(struct target *target, +- struct watchpoint *watchpoint) +-{ +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); +- +- if (nds32_v2->next_hbr_index <= 0) +- return ERROR_FAIL; +- +- /* update next place to put hardware breakpoint */ +- nds32_v2->next_hbr_index--; +- +- return ERROR_OK; +-} +- +-static int nds32_v2_get_exception_address(struct nds32 *nds32, +- uint32_t *address, uint32_t reason) +-{ +- struct aice_port_s *aice = target_to_aice(nds32->target); +- +- aice_read_register(aice, IR4, address); /* read $EVA directly */ +- +- /* TODO: hit multiple watchpoints */ +- +- return ERROR_OK; +-} +- +-/** +- * find out which watchpoint hits +- * get exception address and compare the address to watchpoints +- */ +-static int nds32_v2_hit_watchpoint(struct target *target, +- struct watchpoint **hit_watchpoint) +-{ +- uint32_t exception_address; +- struct watchpoint *wp; +- static struct watchpoint scan_all_watchpoint; +- struct nds32 *nds32 = target_to_nds32(target); +- +- scan_all_watchpoint.address = 0; +- scan_all_watchpoint.rw = WPT_WRITE; +- scan_all_watchpoint.next = 0; +- scan_all_watchpoint.unique_id = 0x5CA8; +- +- exception_address = nds32->watched_address; +- +- if (exception_address == 0) { +- /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */ +- *hit_watchpoint = &scan_all_watchpoint; +- return ERROR_OK; +- } +- +- for (wp = target->watchpoints; wp; wp = wp->next) { +- if (((exception_address ^ wp->address) & (~wp->mask)) == 0) { +- /* TODO: dispel false match */ +- *hit_watchpoint = wp; +- return ERROR_OK; +- } +- } +- +- return ERROR_FAIL; +-} +- +-static int nds32_v2_run_algorithm(struct target *target, +- int num_mem_params, +- struct mem_param *mem_params, +- int num_reg_params, +- struct reg_param *reg_params, +- target_addr_t entry_point, +- target_addr_t exit_point, +- int timeout_ms, +- void *arch_info) +-{ +- LOG_WARNING("Not implemented: %s", __func__); +- +- return ERROR_FAIL; +-} +- +-static int nds32_v2_target_create(struct target *target, Jim_Interp *interp) +-{ +- struct nds32_v2_common *nds32_v2; +- +- nds32_v2 = calloc(1, sizeof(*nds32_v2)); +- if (!nds32_v2) +- return ERROR_FAIL; +- +- nds32_v2->nds32.register_map = nds32_v2_register_mapping; +- nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason; +- nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry; +- nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state; +- nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address; +- +- nds32_init_arch_info(target, &(nds32_v2->nds32)); +- +- return ERROR_OK; +-} +- +-static int nds32_v2_init_target(struct command_context *cmd_ctx, +- struct target *target) +-{ +- /* Initialize anything we can set up without talking to the target */ +- +- struct nds32 *nds32 = target_to_nds32(target); +- +- nds32_init(nds32); +- +- return ERROR_OK; +-} +- +-/* talk to the target and set things up */ +-static int nds32_v2_examine(struct target *target) +-{ +- struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); +- struct nds32 *nds32 = &(nds32_v2->nds32); +- struct aice_port_s *aice = target_to_aice(target); +- +- if (!target_was_examined(target)) { +- CHECK_RETVAL(nds32_edm_config(nds32)); +- +- if (nds32->reset_halt_as_examine) +- CHECK_RETVAL(nds32_reset_halt(nds32)); +- } +- +- uint32_t edm_cfg; +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); +- +- /* get the number of hardware breakpoints */ +- nds32_v2->n_hbr = (edm_cfg & 0x7) + 1; +- +- nds32_v2->next_hbr_index = 0; +- +- LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target), +- nds32_v2->n_hbr); +- +- nds32->target->state = TARGET_RUNNING; +- nds32->target->debug_reason = DBG_REASON_NOTHALTED; +- +- target_set_examined(target); +- +- return ERROR_OK; +-} +- +-static int nds32_v2_translate_address(struct target *target, target_addr_t *address) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- target_addr_t physical_address; +- +- /* Following conditions need to do address translation +- * 1. BUS mode +- * 2. CPU mode under maximum interrupt level */ +- if ((memory->access_channel == NDS_MEMORY_ACC_BUS) || +- ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- nds32_reach_max_interrupt_level(nds32))) { +- if (target->type->virt2phys(target, *address, &physical_address) == ERROR_OK) +- *address = physical_address; +- else +- return ERROR_FAIL; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v2_read_buffer(struct target *target, target_addr_t address, +- uint32_t size, uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- /* BUG: If access range crosses multiple pages, the translation will not correct +- * for second page or so. */ +- +- nds32_v2_translate_address(target, &address); +- +- return nds32_read_buffer(target, address, size, buffer); +-} +- +-static int nds32_v2_write_buffer(struct target *target, target_addr_t address, +- uint32_t size, const uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- /* BUG: If access range crosses multiple pages, the translation will not correct +- * for second page or so. */ +- +- nds32_v2_translate_address(target, &address); +- +- return nds32_write_buffer(target, address, size, buffer); +-} +- +-static int nds32_v2_read_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- /* BUG: If access range crosses multiple pages, the translation will not correct +- * for second page or so. */ +- +- nds32_v2_translate_address(target, &address); +- +- return nds32_read_memory(target, address, size, count, buffer); +-} +- +-static int nds32_v2_write_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, const uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- /* BUG: If access range crosses multiple pages, the translation will not correct +- * for second page or so. */ +- +- nds32_v2_translate_address(target, &address); +- +- return nds32_write_memory(target, address, size, count, buffer); +-} +- +-/** Holds methods for V2 targets. */ +-struct target_type nds32_v2_target = { +- .name = "nds32_v2", +- +- .poll = nds32_poll, +- .arch_state = nds32_arch_state, +- +- .target_request_data = nds32_v2_target_request_data, +- +- .halt = nds32_halt, +- .resume = nds32_resume, +- .step = nds32_step, +- +- .assert_reset = nds32_assert_reset, +- .deassert_reset = nds32_v2_deassert_reset, +- +- /* register access */ +- .get_gdb_reg_list = nds32_get_gdb_reg_list, +- +- /* memory access */ +- .read_buffer = nds32_v2_read_buffer, +- .write_buffer = nds32_v2_write_buffer, +- .read_memory = nds32_v2_read_memory, +- .write_memory = nds32_v2_write_memory, +- +- .checksum_memory = nds32_v2_checksum_memory, +- +- /* breakpoint/watchpoint */ +- .add_breakpoint = nds32_v2_add_breakpoint, +- .remove_breakpoint = nds32_v2_remove_breakpoint, +- .add_watchpoint = nds32_v2_add_watchpoint, +- .remove_watchpoint = nds32_v2_remove_watchpoint, +- .hit_watchpoint = nds32_v2_hit_watchpoint, +- +- /* MMU */ +- .mmu = nds32_mmu, +- .virt2phys = nds32_virtual_to_physical, +- .read_phys_memory = nds32_read_phys_memory, +- .write_phys_memory = nds32_write_phys_memory, +- +- .run_algorithm = nds32_v2_run_algorithm, +- +- .commands = nds32_command_handlers, +- .target_create = nds32_v2_target_create, +- .init_target = nds32_v2_init_target, +- .examine = nds32_v2_examine, +-}; +diff --git a/src/target/nds32_v2.h b/src/target/nds32_v2.h +deleted file mode 100644 +index 3c3010869..000000000 +--- a/src/target/nds32_v2.h ++++ /dev/null +@@ -1,31 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_V2_H +-#define OPENOCD_TARGET_NDS32_V2_H +- +-#include "nds32.h" +- +-struct nds32_v2_common { +- struct nds32 nds32; +- +- uint32_t backup_ir0; +- +- /** number of hardware breakpoints */ +- int32_t n_hbr; +- +- /** next hardware breakpoint index */ +- /** increase from low index to high index */ +- int32_t next_hbr_index; +-}; +- +-static inline struct nds32_v2_common *target_to_nds32_v2(struct target *target) +-{ +- return container_of(target->arch_info, struct nds32_v2_common, nds32); +-} +- +-#endif /* OPENOCD_TARGET_NDS32_V2_H */ +diff --git a/src/target/nds32_v3.c b/src/target/nds32_v3.c +deleted file mode 100644 +index 9d02e5ac9..000000000 +--- a/src/target/nds32_v3.c ++++ /dev/null +@@ -1,510 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include "breakpoints.h" +-#include "nds32_cmd.h" +-#include "nds32_aice.h" +-#include "nds32_v3.h" +-#include "nds32_v3_common.h" +- +-static int nds32_v3_activate_hardware_breakpoint(struct target *target) +-{ +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct breakpoint *bp; +- int32_t hbr_index = nds32_v3->next_hbr_index; +- +- for (bp = target->breakpoints; bp; bp = bp->next) { +- if (bp->type == BKPT_SOFT) { +- /* already set at nds32_v3_add_breakpoint() */ +- continue; +- } else if (bp->type == BKPT_HARD) { +- hbr_index--; +- /* set address */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address); +- /* set mask */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0); +- /* set value */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0); +- +- if (nds32_v3->nds32.memory.address_translation) +- /* enable breakpoint (virtual address) */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2); +- else +- /* enable breakpoint (physical address) */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA); +- +- LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index, +- bp->address); +- } else { +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3_deactivate_hardware_breakpoint(struct target *target) +-{ +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct breakpoint *bp; +- int32_t hbr_index = nds32_v3->next_hbr_index; +- +- for (bp = target->breakpoints; bp; bp = bp->next) { +- if (bp->type == BKPT_SOFT) { +- continue; +- } else if (bp->type == BKPT_HARD) { +- hbr_index--; +- /* disable breakpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0); +- } else { +- return ERROR_FAIL; +- } +- +- LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index, +- bp->address); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3_activate_hardware_watchpoint(struct target *target) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- struct watchpoint *wp; +- int32_t wp_num = 0; +- uint32_t wp_config = 0; +- bool ld_stop, st_stop; +- +- if (nds32_v3->nds32.global_stop) +- ld_stop = st_stop = false; +- +- for (wp = target->watchpoints; wp; wp = wp->next) { +- +- if (wp_num < nds32_v3->used_n_wp) { +- wp->mask = wp->length - 1; +- if ((wp->address % wp->length) != 0) +- wp->mask = (wp->mask << 1) + 1; +- +- if (wp->rw == WPT_READ) +- wp_config = 0x3; +- else if (wp->rw == WPT_WRITE) +- wp_config = 0x5; +- else if (wp->rw == WPT_ACCESS) +- wp_config = 0x7; +- +- /* set/unset physical address bit of BPCn according to PSW.DT */ +- if (nds32_v3->nds32.memory.address_translation == false) +- wp_config |= 0x8; +- +- /* set address */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, +- wp->address - (wp->address % wp->length)); +- /* set mask */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); +- /* enable watchpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); +- /* set value */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0); +- +- LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, +- wp_num, wp->address, wp->mask); +- +- wp_num++; +- } else if (nds32_v3->nds32.global_stop) { +- if (wp->rw == WPT_READ) +- ld_stop = true; +- else if (wp->rw == WPT_WRITE) +- st_stop = true; +- else if (wp->rw == WPT_ACCESS) +- ld_stop = st_stop = true; +- } +- } +- +- if (nds32_v3->nds32.global_stop) { +- uint32_t edm_ctl; +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); +- if (ld_stop) +- edm_ctl |= 0x10; +- if (st_stop) +- edm_ctl |= 0x20; +- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3_deactivate_hardware_watchpoint(struct target *target) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- int32_t wp_num = 0; +- struct watchpoint *wp; +- bool clean_global_stop = false; +- +- for (wp = target->watchpoints; wp; wp = wp->next) { +- +- if (wp_num < nds32_v3->used_n_wp) { +- /* disable watchpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); +- +- LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR +- " mask %08" PRIx32, wp_num, +- wp->address, wp->mask); +- wp_num++; +- } else if (nds32_v3->nds32.global_stop) { +- clean_global_stop = true; +- } +- } +- +- if (clean_global_stop) { +- uint32_t edm_ctl; +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); +- edm_ctl = edm_ctl & (~0x30); +- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3_check_interrupt_stack(struct nds32 *nds32) +-{ +- uint32_t val_ir0; +- uint32_t value; +- +- /* Save interrupt level */ +- nds32_get_mapped_reg(nds32, IR0, &val_ir0); +- nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; +- +- if (nds32_reach_max_interrupt_level(nds32)) +- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", +- nds32->current_interrupt_level); +- +- /* backup $ir4 & $ir6 to avoid suppressed exception overwrite */ +- nds32_get_mapped_reg(nds32, IR4, &value); +- nds32_get_mapped_reg(nds32, IR6, &value); +- +- return ERROR_OK; +-} +- +-static int nds32_v3_restore_interrupt_stack(struct nds32 *nds32) +-{ +- uint32_t value; +- +- /* get backup value from cache */ +- /* then set back to make the register dirty */ +- nds32_get_mapped_reg(nds32, IR0, &value); +- nds32_set_mapped_reg(nds32, IR0, value); +- +- nds32_get_mapped_reg(nds32, IR4, &value); +- nds32_set_mapped_reg(nds32, IR4, value); +- +- nds32_get_mapped_reg(nds32, IR6, &value); +- nds32_set_mapped_reg(nds32, IR6, value); +- +- return ERROR_OK; +-} +- +-static int nds32_v3_deassert_reset(struct target *target) +-{ +- int retval; +- struct aice_port_s *aice = target_to_aice(target); +- bool switch_to_v3_stack = false; +- uint32_t value_edm_ctl; +- +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &value_edm_ctl); +- if (((value_edm_ctl >> 6) & 0x1) == 0) { /* reset to V2 EDM mode */ +- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, value_edm_ctl | (0x1 << 6)); +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &value_edm_ctl); +- if (((value_edm_ctl >> 6) & 0x1) == 1) +- switch_to_v3_stack = true; +- } else +- switch_to_v3_stack = false; +- +- CHECK_RETVAL(nds32_poll(target)); +- +- if (target->state != TARGET_HALTED) { +- /* reset only */ +- LOG_WARNING("%s: ran after reset and before halt ...", +- target_name(target)); +- retval = target_halt(target); +- if (retval != ERROR_OK) +- return retval; +- +- } else { +- /* reset-halt */ +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- struct nds32 *nds32 = &(nds32_v3->nds32); +- uint32_t value; +- uint32_t interrupt_level; +- +- if (switch_to_v3_stack == true) { +- /* PSW.INTL-- */ +- nds32_get_mapped_reg(nds32, IR0, &value); +- interrupt_level = (value >> 1) & 0x3; +- interrupt_level--; +- value &= ~(0x6); +- value |= (interrupt_level << 1); +- value |= 0x400; /* set PSW.DEX */ +- nds32_set_mapped_reg(nds32, IR0, value); +- +- /* copy IPC to OIPC */ +- if ((interrupt_level + 1) < nds32->max_interrupt_level) { +- nds32_get_mapped_reg(nds32, IR9, &value); +- nds32_set_mapped_reg(nds32, IR11, value); +- } +- } +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3_add_breakpoint(struct target *target, +- struct breakpoint *breakpoint) +-{ +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- struct nds32 *nds32 = &(nds32_v3->nds32); +- int result; +- +- if (breakpoint->type == BKPT_HARD) { +- /* check hardware resource */ +- if (nds32_v3->n_hbr <= nds32_v3->next_hbr_index) { +- LOG_WARNING("<-- TARGET WARNING! Insert too many " +- "hardware breakpoints/watchpoints! " +- "The limit of combined hardware " +- "breakpoints/watchpoints is %" PRId32 ". -->", +- nds32_v3->n_hbr); +- LOG_WARNING("<-- TARGET STATUS: Inserted number of " +- "hardware breakpoint: %" PRId32 ", hardware " +- "watchpoints: %" PRId32 ". -->", +- nds32_v3->next_hbr_index - nds32_v3->used_n_wp, +- nds32_v3->used_n_wp); +- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; +- } +- +- /* update next place to put hardware breakpoint */ +- nds32_v3->next_hbr_index++; +- +- /* hardware breakpoint insertion occurs before 'continue' actually */ +- return ERROR_OK; +- } else if (breakpoint->type == BKPT_SOFT) { +- result = nds32_add_software_breakpoint(target, breakpoint); +- if (result != ERROR_OK) { +- /* auto convert to hardware breakpoint if failed */ +- if (nds32->auto_convert_hw_bp) { +- /* convert to hardware breakpoint */ +- breakpoint->type = BKPT_HARD; +- +- return nds32_v3_add_breakpoint(target, breakpoint); +- } +- } +- +- return result; +- } else /* unrecognized breakpoint type */ +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int nds32_v3_remove_breakpoint(struct target *target, +- struct breakpoint *breakpoint) +-{ +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- +- if (breakpoint->type == BKPT_HARD) { +- if (nds32_v3->next_hbr_index <= 0) +- return ERROR_FAIL; +- +- /* update next place to put hardware breakpoint */ +- nds32_v3->next_hbr_index--; +- +- /* hardware breakpoint removal occurs after 'halted' actually */ +- return ERROR_OK; +- } else if (breakpoint->type == BKPT_SOFT) { +- return nds32_remove_software_breakpoint(target, breakpoint); +- } else /* unrecognized breakpoint type */ +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int nds32_v3_add_watchpoint(struct target *target, +- struct watchpoint *watchpoint) +-{ +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- +- /* check hardware resource */ +- if (nds32_v3->n_hbr <= nds32_v3->next_hbr_index) { +- /* No hardware resource */ +- if (nds32_v3->nds32.global_stop) { +- LOG_WARNING("<-- TARGET WARNING! The number of " +- "watchpoints exceeds the hardware " +- "resources. Stop at every load/store " +- "instruction to check for watchpoint matches. -->"); +- return ERROR_OK; +- } +- +- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " +- "breakpoints/watchpoints! The limit of combined " +- "hardware breakpoints/watchpoints is %" PRId32 ". -->", +- nds32_v3->n_hbr); +- LOG_WARNING("<-- TARGET STATUS: Inserted number of " +- "hardware breakpoint: %" PRId32 ", hardware " +- "watchpoints: %" PRId32 ". -->", +- nds32_v3->next_hbr_index - nds32_v3->used_n_wp, +- nds32_v3->used_n_wp); +- +- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; +- } +- +- /* update next place to put hardware watchpoint */ +- nds32_v3->next_hbr_index++; +- nds32_v3->used_n_wp++; +- +- return ERROR_OK; +-} +- +-static int nds32_v3_remove_watchpoint(struct target *target, +- struct watchpoint *watchpoint) +-{ +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- +- if (nds32_v3->next_hbr_index <= 0) { +- if (nds32_v3->nds32.global_stop) +- return ERROR_OK; +- +- return ERROR_FAIL; +- } +- +- /* update next place to put hardware breakpoint */ +- nds32_v3->next_hbr_index--; +- nds32_v3->used_n_wp--; +- +- return ERROR_OK; +-} +- +-static struct nds32_v3_common_callback nds32_v3_common_callback = { +- .check_interrupt_stack = nds32_v3_check_interrupt_stack, +- .restore_interrupt_stack = nds32_v3_restore_interrupt_stack, +- .activate_hardware_breakpoint = nds32_v3_activate_hardware_breakpoint, +- .activate_hardware_watchpoint = nds32_v3_activate_hardware_watchpoint, +- .deactivate_hardware_breakpoint = nds32_v3_deactivate_hardware_breakpoint, +- .deactivate_hardware_watchpoint = nds32_v3_deactivate_hardware_watchpoint, +-}; +- +-static int nds32_v3_target_create(struct target *target, Jim_Interp *interp) +-{ +- struct nds32_v3_common *nds32_v3; +- +- nds32_v3 = calloc(1, sizeof(*nds32_v3)); +- if (!nds32_v3) +- return ERROR_FAIL; +- +- nds32_v3_common_register_callback(&nds32_v3_common_callback); +- nds32_v3_target_create_common(target, &(nds32_v3->nds32)); +- +- return ERROR_OK; +-} +- +-/* talk to the target and set things up */ +-static int nds32_v3_examine(struct target *target) +-{ +- struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); +- struct nds32 *nds32 = &(nds32_v3->nds32); +- struct aice_port_s *aice = target_to_aice(target); +- +- if (!target_was_examined(target)) { +- CHECK_RETVAL(nds32_edm_config(nds32)); +- +- if (nds32->reset_halt_as_examine) +- CHECK_RETVAL(nds32_reset_halt(nds32)); +- } +- +- uint32_t edm_cfg; +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); +- +- /* get the number of hardware breakpoints */ +- nds32_v3->n_hbr = (edm_cfg & 0x7) + 1; +- +- /* low interference profiling */ +- if (edm_cfg & 0x100) +- nds32_v3->low_interference_profile = true; +- else +- nds32_v3->low_interference_profile = false; +- +- nds32_v3->next_hbr_index = 0; +- nds32_v3->used_n_wp = 0; +- +- LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target), +- nds32_v3->n_hbr); +- +- nds32->target->state = TARGET_RUNNING; +- nds32->target->debug_reason = DBG_REASON_NOTHALTED; +- +- target_set_examined(target); +- +- return ERROR_OK; +-} +- +-/** Holds methods for Andes1337 targets. */ +-struct target_type nds32_v3_target = { +- .name = "nds32_v3", +- +- .poll = nds32_poll, +- .arch_state = nds32_arch_state, +- +- .target_request_data = nds32_v3_target_request_data, +- +- .halt = nds32_halt, +- .resume = nds32_resume, +- .step = nds32_step, +- +- .assert_reset = nds32_assert_reset, +- .deassert_reset = nds32_v3_deassert_reset, +- +- /* register access */ +- .get_gdb_reg_list = nds32_get_gdb_reg_list, +- +- /* memory access */ +- .read_buffer = nds32_v3_read_buffer, +- .write_buffer = nds32_v3_write_buffer, +- .read_memory = nds32_v3_read_memory, +- .write_memory = nds32_v3_write_memory, +- +- .checksum_memory = nds32_v3_checksum_memory, +- +- /* breakpoint/watchpoint */ +- .add_breakpoint = nds32_v3_add_breakpoint, +- .remove_breakpoint = nds32_v3_remove_breakpoint, +- .add_watchpoint = nds32_v3_add_watchpoint, +- .remove_watchpoint = nds32_v3_remove_watchpoint, +- .hit_watchpoint = nds32_v3_hit_watchpoint, +- +- /* MMU */ +- .mmu = nds32_mmu, +- .virt2phys = nds32_virtual_to_physical, +- .read_phys_memory = nds32_read_phys_memory, +- .write_phys_memory = nds32_write_phys_memory, +- +- .run_algorithm = nds32_v3_run_algorithm, +- +- .commands = nds32_command_handlers, +- .target_create = nds32_v3_target_create, +- .init_target = nds32_v3_init_target, +- .examine = nds32_v3_examine, +- +- .get_gdb_fileio_info = nds32_get_gdb_fileio_info, +- .gdb_fileio_end = nds32_gdb_fileio_end, +- +- .profiling = nds32_profiling, +-}; +diff --git a/src/target/nds32_v3.h b/src/target/nds32_v3.h +deleted file mode 100644 +index 389838d8f..000000000 +--- a/src/target/nds32_v3.h ++++ /dev/null +@@ -1,34 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_V3_H +-#define OPENOCD_TARGET_NDS32_V3_H +- +-#include "nds32.h" +- +-struct nds32_v3_common { +- struct nds32 nds32; +- +- /** number of hardware breakpoints */ +- int32_t n_hbr; +- +- /** number of used hardware watchpoints */ +- int32_t used_n_wp; +- +- /** next hardware breakpoint index */ +- int32_t next_hbr_index; +- +- /** low interference profiling */ +- bool low_interference_profile; +-}; +- +-static inline struct nds32_v3_common *target_to_nds32_v3(struct target *target) +-{ +- return container_of(target->arch_info, struct nds32_v3_common, nds32); +-} +- +-#endif /* OPENOCD_TARGET_NDS32_V3_H */ +diff --git a/src/target/nds32_v3_common.c b/src/target/nds32_v3_common.c +deleted file mode 100644 +index f2efab441..000000000 +--- a/src/target/nds32_v3_common.c ++++ /dev/null +@@ -1,664 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include "breakpoints.h" +-#include "nds32_reg.h" +-#include "nds32_disassembler.h" +-#include "nds32.h" +-#include "nds32_aice.h" +-#include "nds32_v3_common.h" +- +-static struct nds32_v3_common_callback *v3_common_callback; +- +-static int nds32_v3_register_mapping(struct nds32 *nds32, int reg_no) +-{ +- if (reg_no == PC) +- return IR11; +- +- return reg_no; +-} +- +-static int nds32_v3_get_debug_reason(struct nds32 *nds32, uint32_t *reason) +-{ +- uint32_t edmsw; +- struct aice_port_s *aice = target_to_aice(nds32->target); +- aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw); +- +- *reason = (edmsw >> 12) & 0x0F; +- +- return ERROR_OK; +-} +- +-/** +- * Save processor state. This is called after a HALT instruction +- * succeeds, and on other occasions the processor enters debug mode +- * (breakpoint, watchpoint, etc). +- */ +-static int nds32_v3_debug_entry(struct nds32 *nds32, bool enable_watchpoint) +-{ +- LOG_DEBUG("nds32_v3_debug_entry"); +- +- enum target_state backup_state = nds32->target->state; +- nds32->target->state = TARGET_HALTED; +- +- if (nds32->init_arch_info_after_halted == false) { +- /* init architecture info according to config registers */ +- CHECK_RETVAL(nds32_config(nds32)); +- +- nds32->init_arch_info_after_halted = true; +- } +- +- /* REVISIT entire cache should already be invalid !!! */ +- register_cache_invalidate(nds32->core_cache); +- +- /* deactivate all hardware breakpoints */ +- CHECK_RETVAL(v3_common_callback->deactivate_hardware_breakpoint(nds32->target)); +- +- if (enable_watchpoint) +- CHECK_RETVAL(v3_common_callback->deactivate_hardware_watchpoint(nds32->target)); +- +- struct breakpoint *syscall_break = &(nds32->syscall_break); +- if (nds32->virtual_hosting) { +- if (syscall_break->is_set) { +- /** disable virtual hosting */ +- +- /* remove breakpoint at syscall entry */ +- target_remove_breakpoint(nds32->target, syscall_break); +- syscall_break->is_set = false; +- +- uint32_t value_pc; +- nds32_get_mapped_reg(nds32, PC, &value_pc); +- if (value_pc == syscall_break->address) +- /** process syscall for virtual hosting */ +- nds32->hit_syscall = true; +- } +- } +- +- if (nds32_examine_debug_reason(nds32) != ERROR_OK) { +- nds32->target->state = backup_state; +- +- /* re-activate all hardware breakpoints & watchpoints */ +- CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(nds32->target)); +- +- if (enable_watchpoint) +- CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(nds32->target)); +- +- return ERROR_FAIL; +- } +- +- /* Save registers. */ +- nds32_full_context(nds32); +- +- /* check interrupt level */ +- v3_common_callback->check_interrupt_stack(nds32); +- +- return ERROR_OK; +-} +- +-/** +- * Restore processor state. +- */ +-static int nds32_v3_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint) +-{ +- LOG_DEBUG("nds32_v3_leave_debug_state"); +- +- struct target *target = nds32->target; +- +- /* activate all hardware breakpoints */ +- CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(target)); +- +- if (enable_watchpoint) { +- /* activate all watchpoints */ +- CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(target)); +- } +- +- /* restore interrupt stack */ +- v3_common_callback->restore_interrupt_stack(nds32); +- +- /* REVISIT once we start caring about MMU and cache state, +- * address it here ... +- */ +- +- /* restore PSW, PC, and R0 ... after flushing any modified +- * registers. +- */ +- CHECK_RETVAL(nds32_restore_context(target)); +- +- if (nds32->virtual_hosting) { +- /** enable virtual hosting */ +- uint32_t value_ir3; +- uint32_t entry_size; +- uint32_t syscall_address; +- +- /* get syscall entry address */ +- nds32_get_mapped_reg(nds32, IR3, &value_ir3); +- entry_size = 0x4 << (((value_ir3 >> 14) & 0x3) << 1); +- syscall_address = (value_ir3 & 0xFFFF0000) + entry_size * 8; /* The index of SYSCALL is 8 */ +- +- if (nds32->hit_syscall) { +- /* single step to skip syscall entry */ +- /* use IRET to skip syscall */ +- struct aice_port_s *aice = target_to_aice(target); +- uint32_t value_ir9; +- uint32_t value_ir6; +- uint32_t syscall_id; +- +- nds32_get_mapped_reg(nds32, IR6, &value_ir6); +- syscall_id = (value_ir6 >> 16) & 0x7FFF; +- +- if (syscall_id == NDS32_SYSCALL_EXIT) { +- /* If target hits exit syscall, do not use IRET to skip handler. */ +- aice_step(aice); +- } else { +- /* use api->read/write_reg to skip nds32 register cache */ +- uint32_t value_dimbr; +- aice_read_debug_reg(aice, NDS_EDM_SR_DIMBR, &value_dimbr); +- aice_write_register(aice, IR11, value_dimbr + 0xC); +- +- aice_read_register(aice, IR9, &value_ir9); +- value_ir9 += 4; /* syscall is always 4 bytes */ +- aice_write_register(aice, IR9, value_ir9); +- +- /* backup hardware breakpoint 0 */ +- uint32_t backup_bpa, backup_bpam, backup_bpc; +- aice_read_debug_reg(aice, NDS_EDM_SR_BPA0, &backup_bpa); +- aice_read_debug_reg(aice, NDS_EDM_SR_BPAM0, &backup_bpam); +- aice_read_debug_reg(aice, NDS_EDM_SR_BPC0, &backup_bpc); +- +- /* use hardware breakpoint 0 to stop cpu after skipping syscall */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, value_ir9); +- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, 0); +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, 0xA); +- +- /* Execute two IRET. +- * First IRET is used to quit debug mode. +- * Second IRET is used to quit current syscall. */ +- uint32_t dim_inst[4] = {NOP, NOP, IRET, IRET}; +- aice_execute(aice, dim_inst, 4); +- +- /* restore origin hardware breakpoint 0 */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, backup_bpa); +- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, backup_bpam); +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, backup_bpc); +- } +- +- nds32->hit_syscall = false; +- } +- +- /* insert breakpoint at syscall entry */ +- struct breakpoint *syscall_break = &(nds32->syscall_break); +- +- syscall_break->address = syscall_address; +- syscall_break->type = BKPT_SOFT; +- syscall_break->is_set = true; +- target_add_breakpoint(target, syscall_break); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3_get_exception_address(struct nds32 *nds32, +- uint32_t *address, uint32_t reason) +-{ +- LOG_DEBUG("nds32_v3_get_exception_address"); +- +- struct aice_port_s *aice = target_to_aice(nds32->target); +- struct target *target = nds32->target; +- uint32_t edmsw; +- uint32_t edm_cfg; +- uint32_t match_bits; +- uint32_t match_count; +- int32_t i; +- static int32_t number_of_hard_break; +- uint32_t bp_control; +- +- if (number_of_hard_break == 0) { +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); +- number_of_hard_break = (edm_cfg & 0x7) + 1; +- } +- +- aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw); +- /* clear matching bits (write-one-clear) */ +- aice_write_debug_reg(aice, NDS_EDM_SR_EDMSW, edmsw); +- match_bits = (edmsw >> 4) & 0xFF; +- match_count = 0; +- for (i = 0 ; i < number_of_hard_break ; i++) { +- if (match_bits & (1 << i)) { +- aice_read_debug_reg(aice, NDS_EDM_SR_BPA0 + i, address); +- match_count++; +- +- /* If target hits multiple read/access watchpoint, +- * select the first one. */ +- aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &bp_control); +- if (0x3 == (bp_control & 0x3)) { +- match_count = 1; +- break; +- } +- } +- } +- +- if (match_count > 1) { /* multiple hits */ +- *address = 0; +- return ERROR_OK; +- } else if (match_count == 1) { +- uint32_t val_pc; +- uint32_t opcode; +- struct nds32_instruction instruction; +- struct watchpoint *wp; +- bool hit; +- +- nds32_get_mapped_reg(nds32, PC, &val_pc); +- +- if ((reason == NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE) || +- (reason == NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE)) { +- if (edmsw & 0x4) /* check EDMSW.IS_16BIT */ +- val_pc -= 2; +- else +- val_pc -= 4; +- } +- +- nds32_read_opcode(nds32, val_pc, &opcode); +- nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction); +- +- LOG_DEBUG("PC: 0x%08" PRIx32 ", access start: 0x%08" PRIx32 ", end: 0x%08" PRIx32, +- val_pc, instruction.access_start, instruction.access_end); +- +- /* check if multiple hits in the access range */ +- uint32_t in_range_watch_count = 0; +- for (wp = target->watchpoints; wp; wp = wp->next) { +- if ((instruction.access_start <= wp->address) && +- (wp->address < instruction.access_end)) +- in_range_watch_count++; +- } +- if (in_range_watch_count > 1) { +- /* Hit LSMW instruction. */ +- *address = 0; +- return ERROR_OK; +- } +- +- /* dispel false match */ +- hit = false; +- for (wp = target->watchpoints; wp; wp = wp->next) { +- if (((*address ^ wp->address) & (~wp->mask)) == 0) { +- uint32_t watch_start; +- uint32_t watch_end; +- +- watch_start = wp->address; +- watch_end = wp->address + wp->length; +- +- if ((watch_end <= instruction.access_start) || +- (instruction.access_end <= watch_start)) +- continue; +- +- hit = true; +- break; +- } +- } +- +- if (hit) +- return ERROR_OK; +- else +- return ERROR_FAIL; +- } else if (match_count == 0) { +- /* global stop is precise exception */ +- if ((reason == NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP) && nds32->global_stop) { +- /* parse instruction to get correct access address */ +- uint32_t val_pc; +- uint32_t opcode; +- struct nds32_instruction instruction; +- +- nds32_get_mapped_reg(nds32, PC, &val_pc); +- nds32_read_opcode(nds32, val_pc, &opcode); +- nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction); +- +- *address = instruction.access_start; +- +- return ERROR_OK; +- } +- } +- +- *address = 0xFFFFFFFF; +- return ERROR_FAIL; +-} +- +-void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback) +-{ +- v3_common_callback = callback; +-} +- +-/** target_type functions: */ +-/* target request support */ +-int nds32_v3_target_request_data(struct target *target, +- uint32_t size, uint8_t *buffer) +-{ +- /* AndesCore could use DTR register to communicate with OpenOCD +- * to output messages +- * Target data will be put in buffer +- * The format of DTR is as follow +- * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd +- * target_req_cmd has three possible values: +- * TARGET_REQ_TRACEMSG +- * TARGET_REQ_DEBUGMSG +- * TARGET_REQ_DEBUGCHAR +- * if size == 0, target will call target_asciimsg(), +- * else call target_hexmsg() +- */ +- LOG_WARNING("Not implemented: %s", __func__); +- +- return ERROR_OK; +-} +- +-int nds32_v3_checksum_memory(struct target *target, +- target_addr_t address, uint32_t count, uint32_t *checksum) +-{ +- LOG_WARNING("Not implemented: %s", __func__); +- +- return ERROR_FAIL; +-} +- +-/** +- * find out which watchpoint hits +- * get exception address and compare the address to watchpoints +- */ +-int nds32_v3_hit_watchpoint(struct target *target, +- struct watchpoint **hit_watchpoint) +-{ +- static struct watchpoint scan_all_watchpoint; +- +- uint32_t exception_address; +- struct watchpoint *wp; +- struct nds32 *nds32 = target_to_nds32(target); +- +- exception_address = nds32->watched_address; +- +- if (exception_address == 0xFFFFFFFF) +- return ERROR_FAIL; +- +- if (exception_address == 0) { +- scan_all_watchpoint.address = 0; +- scan_all_watchpoint.rw = WPT_WRITE; +- scan_all_watchpoint.next = 0; +- scan_all_watchpoint.unique_id = 0x5CA8; +- +- *hit_watchpoint = &scan_all_watchpoint; +- return ERROR_OK; +- } +- +- for (wp = target->watchpoints; wp; wp = wp->next) { +- if (((exception_address ^ wp->address) & (~wp->mask)) == 0) { +- *hit_watchpoint = wp; +- +- return ERROR_OK; +- } +- } +- +- return ERROR_FAIL; +-} +- +-int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32) +-{ +- nds32->register_map = nds32_v3_register_mapping; +- nds32->get_debug_reason = nds32_v3_get_debug_reason; +- nds32->enter_debug_state = nds32_v3_debug_entry; +- nds32->leave_debug_state = nds32_v3_leave_debug_state; +- nds32->get_watched_address = nds32_v3_get_exception_address; +- +- /* Init target->arch_info in nds32_init_arch_info(). +- * After this, user could use target_to_nds32() to get nds32 object */ +- nds32_init_arch_info(target, nds32); +- +- return ERROR_OK; +-} +- +-int nds32_v3_run_algorithm(struct target *target, +- int num_mem_params, +- struct mem_param *mem_params, +- int num_reg_params, +- struct reg_param *reg_params, +- target_addr_t entry_point, +- target_addr_t exit_point, +- int timeout_ms, +- void *arch_info) +-{ +- LOG_WARNING("Not implemented: %s", __func__); +- +- return ERROR_FAIL; +-} +- +-int nds32_v3_read_buffer(struct target *target, target_addr_t address, +- uint32_t size, uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- target_addr_t physical_address; +- /* BUG: If access range crosses multiple pages, the translation will not correct +- * for second page or so. */ +- +- /* When DEX is set to one, hardware will enforce the following behavior without +- * modifying the corresponding control bits in PSW. +- * +- * Disable all interrupts +- * Become superuser mode +- * Turn off IT/DT +- * Use MMU_CFG.DE as the data access endian +- * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted +- * Disable audio special features +- * Disable inline function call +- * +- * Because hardware will turn off IT/DT by default, it MUST translate virtual address +- * to physical address. +- */ +- if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK) +- address = physical_address; +- else +- return ERROR_FAIL; +- +- int result; +- struct aice_port_s *aice = target_to_aice(target); +- /* give arbitrary initial value to avoid warning messages */ +- enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU; +- +- if (nds32->hit_syscall) { +- /* Use bus mode to access memory during virtual hosting */ +- origin_access_channel = memory->access_channel; +- memory->access_channel = NDS_MEMORY_ACC_BUS; +- aice_memory_access(aice, NDS_MEMORY_ACC_BUS); +- } +- +- result = nds32_read_buffer(target, address, size, buffer); +- +- if (nds32->hit_syscall) { +- /* Restore access_channel after virtual hosting */ +- memory->access_channel = origin_access_channel; +- aice_memory_access(aice, origin_access_channel); +- } +- +- return result; +-} +- +-int nds32_v3_write_buffer(struct target *target, target_addr_t address, +- uint32_t size, const uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- target_addr_t physical_address; +- /* BUG: If access range crosses multiple pages, the translation will not correct +- * for second page or so. */ +- +- /* When DEX is set to one, hardware will enforce the following behavior without +- * modifying the corresponding control bits in PSW. +- * +- * Disable all interrupts +- * Become superuser mode +- * Turn off IT/DT +- * Use MMU_CFG.DE as the data access endian +- * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted +- * Disable audio special features +- * Disable inline function call +- * +- * Because hardware will turn off IT/DT by default, it MUST translate virtual address +- * to physical address. +- */ +- if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK) +- address = physical_address; +- else +- return ERROR_FAIL; +- +- if (nds32->hit_syscall) { +- struct aice_port_s *aice = target_to_aice(target); +- enum nds_memory_access origin_access_channel; +- origin_access_channel = memory->access_channel; +- +- /* If target has no cache, use BUS mode to access memory. */ +- if ((memory->dcache.line_size == 0) +- || (memory->dcache.enable == false)) { +- /* There is no Dcache or Dcache is disabled. */ +- memory->access_channel = NDS_MEMORY_ACC_BUS; +- aice_memory_access(aice, NDS_MEMORY_ACC_BUS); +- } +- +- int result; +- result = nds32_gdb_fileio_write_memory(nds32, address, size, buffer); +- +- if (origin_access_channel == NDS_MEMORY_ACC_CPU) { +- memory->access_channel = NDS_MEMORY_ACC_CPU; +- aice_memory_access(aice, NDS_MEMORY_ACC_CPU); +- } +- +- return result; +- } +- +- return nds32_write_buffer(target, address, size, buffer); +-} +- +-int nds32_v3_read_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- target_addr_t physical_address; +- /* BUG: If access range crosses multiple pages, the translation will not correct +- * for second page or so. */ +- +- /* When DEX is set to one, hardware will enforce the following behavior without +- * modifying the corresponding control bits in PSW. +- * +- * Disable all interrupts +- * Become superuser mode +- * Turn off IT/DT +- * Use MMU_CFG.DE as the data access endian +- * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted +- * Disable audio special features +- * Disable inline function call +- * +- * Because hardware will turn off IT/DT by default, it MUST translate virtual address +- * to physical address. +- */ +- if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK) +- address = physical_address; +- else +- return ERROR_FAIL; +- +- struct aice_port_s *aice = target_to_aice(target); +- /* give arbitrary initial value to avoid warning messages */ +- enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU; +- int result; +- +- if (nds32->hit_syscall) { +- /* Use bus mode to access memory during virtual hosting */ +- origin_access_channel = memory->access_channel; +- memory->access_channel = NDS_MEMORY_ACC_BUS; +- aice_memory_access(aice, NDS_MEMORY_ACC_BUS); +- } +- +- result = nds32_read_memory(target, address, size, count, buffer); +- +- if (nds32->hit_syscall) { +- /* Restore access_channel after virtual hosting */ +- memory->access_channel = origin_access_channel; +- aice_memory_access(aice, origin_access_channel); +- } +- +- return result; +-} +- +-int nds32_v3_write_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, const uint8_t *buffer) +-{ +- struct nds32 *nds32 = target_to_nds32(target); +- struct nds32_memory *memory = &(nds32->memory); +- +- if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && +- (target->state != TARGET_HALTED)) { +- LOG_WARNING("target was not halted"); +- return ERROR_TARGET_NOT_HALTED; +- } +- +- target_addr_t physical_address; +- /* BUG: If access range crosses multiple pages, the translation will not correct +- * for second page or so. */ +- +- /* When DEX is set to one, hardware will enforce the following behavior without +- * modifying the corresponding control bits in PSW. +- * +- * Disable all interrupts +- * Become superuser mode +- * Turn off IT/DT +- * Use MMU_CFG.DE as the data access endian +- * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted +- * Disable audio special features +- * Disable inline function call +- * +- * Because hardware will turn off IT/DT by default, it MUST translate virtual address +- * to physical address. +- */ +- if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK) +- address = physical_address; +- else +- return ERROR_FAIL; +- +- return nds32_write_memory(target, address, size, count, buffer); +-} +- +-int nds32_v3_init_target(struct command_context *cmd_ctx, +- struct target *target) +-{ +- /* Initialize anything we can set up without talking to the target */ +- struct nds32 *nds32 = target_to_nds32(target); +- +- nds32_init(nds32); +- +- target->fileio_info = malloc(sizeof(struct gdb_fileio_info)); +- target->fileio_info->identifier = NULL; +- +- return ERROR_OK; +-} +diff --git a/src/target/nds32_v3_common.h b/src/target/nds32_v3_common.h +deleted file mode 100644 +index a98988e5a..000000000 +--- a/src/target/nds32_v3_common.h ++++ /dev/null +@@ -1,50 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_V3_COMMON_H +-#define OPENOCD_TARGET_NDS32_V3_COMMON_H +- +-#include "target.h" +- +-struct nds32_v3_common_callback { +- int (*check_interrupt_stack)(struct nds32 *nds32); +- int (*restore_interrupt_stack)(struct nds32 *nds32); +- int (*activate_hardware_breakpoint)(struct target *target); +- int (*activate_hardware_watchpoint)(struct target *target); +- int (*deactivate_hardware_breakpoint)(struct target *target); +- int (*deactivate_hardware_watchpoint)(struct target *target); +-}; +- +-void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback); +-int nds32_v3_target_request_data(struct target *target, +- uint32_t size, uint8_t *buffer); +-int nds32_v3_checksum_memory(struct target *target, +- target_addr_t address, uint32_t count, uint32_t *checksum); +-int nds32_v3_hit_watchpoint(struct target *target, +- struct watchpoint **hit_watchpoint); +-int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32); +-int nds32_v3_run_algorithm(struct target *target, +- int num_mem_params, +- struct mem_param *mem_params, +- int num_reg_params, +- struct reg_param *reg_params, +- target_addr_t entry_point, +- target_addr_t exit_point, +- int timeout_ms, +- void *arch_info); +-int nds32_v3_read_buffer(struct target *target, target_addr_t address, +- uint32_t size, uint8_t *buffer); +-int nds32_v3_write_buffer(struct target *target, target_addr_t address, +- uint32_t size, const uint8_t *buffer); +-int nds32_v3_read_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, uint8_t *buffer); +-int nds32_v3_write_memory(struct target *target, target_addr_t address, +- uint32_t size, uint32_t count, const uint8_t *buffer); +-int nds32_v3_init_target(struct command_context *cmd_ctx, +- struct target *target); +- +-#endif /* OPENOCD_TARGET_NDS32_V3_COMMON_H */ +diff --git a/src/target/nds32_v3m.c b/src/target/nds32_v3m.c +deleted file mode 100644 +index 6bc549f46..000000000 +--- a/src/target/nds32_v3m.c ++++ /dev/null +@@ -1,495 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include "breakpoints.h" +-#include "nds32_cmd.h" +-#include "nds32_aice.h" +-#include "nds32_v3m.h" +-#include "nds32_v3_common.h" +- +-static int nds32_v3m_activate_hardware_breakpoint(struct target *target) +-{ +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct breakpoint *bp; +- unsigned brp_num = nds32_v3m->n_hbr - 1; +- +- for (bp = target->breakpoints; bp; bp = bp->next) { +- if (bp->type == BKPT_SOFT) { +- /* already set at nds32_v3m_add_breakpoint() */ +- continue; +- } else if (bp->type == BKPT_HARD) { +- /* set address */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + brp_num, bp->address); +- /* set mask */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + brp_num, 0); +- +- if (nds32_v3m->nds32.memory.address_translation) +- /* enable breakpoint (virtual address) */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0x2); +- else +- /* enable breakpoint (physical address) */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0xA); +- +- LOG_DEBUG("Add hardware BP %u at %08" TARGET_PRIxADDR, brp_num, +- bp->address); +- +- brp_num--; +- } else { +- return ERROR_FAIL; +- } +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_deactivate_hardware_breakpoint(struct target *target) +-{ +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct breakpoint *bp; +- unsigned brp_num = nds32_v3m->n_hbr - 1; +- +- for (bp = target->breakpoints; bp; bp = bp->next) { +- if (bp->type == BKPT_SOFT) +- continue; +- else if (bp->type == BKPT_HARD) +- /* disable breakpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0x0); +- else +- return ERROR_FAIL; +- +- LOG_DEBUG("Remove hardware BP %u at %08" TARGET_PRIxADDR, brp_num, +- bp->address); +- +- brp_num--; +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_activate_hardware_watchpoint(struct target *target) +-{ +- struct aice_port_s *aice = target_to_aice(target); +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- struct watchpoint *wp; +- int32_t wp_num = 0; +- uint32_t wp_config = 0; +- bool ld_stop, st_stop; +- +- if (nds32_v3m->nds32.global_stop) +- ld_stop = st_stop = false; +- +- for (wp = target->watchpoints; wp; wp = wp->next) { +- +- if (wp_num < nds32_v3m->used_n_wp) { +- wp->mask = wp->length - 1; +- if ((wp->address % wp->length) != 0) +- wp->mask = (wp->mask << 1) + 1; +- +- if (wp->rw == WPT_READ) +- wp_config = 0x3; +- else if (wp->rw == WPT_WRITE) +- wp_config = 0x5; +- else if (wp->rw == WPT_ACCESS) +- wp_config = 0x7; +- +- /* set/unset physical address bit of BPCn according to PSW.DT */ +- if (nds32_v3m->nds32.memory.address_translation == false) +- wp_config |= 0x8; +- +- /* set address */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, +- wp->address - (wp->address % wp->length)); +- /* set mask */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); +- /* enable watchpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); +- +- LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR +- " mask %08" PRIx32, wp_num, wp->address, wp->mask); +- +- wp_num++; +- } else if (nds32_v3m->nds32.global_stop) { +- if (wp->rw == WPT_READ) +- ld_stop = true; +- else if (wp->rw == WPT_WRITE) +- st_stop = true; +- else if (wp->rw == WPT_ACCESS) +- ld_stop = st_stop = true; +- } +- } +- +- if (nds32_v3m->nds32.global_stop) { +- uint32_t edm_ctl; +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); +- if (ld_stop) +- edm_ctl |= 0x10; +- if (st_stop) +- edm_ctl |= 0x20; +- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_deactivate_hardware_watchpoint(struct target *target) +-{ +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- struct aice_port_s *aice = target_to_aice(target); +- struct watchpoint *wp; +- int32_t wp_num = 0; +- bool clean_global_stop = false; +- +- for (wp = target->watchpoints; wp; wp = wp->next) { +- +- if (wp_num < nds32_v3m->used_n_wp) { +- /* disable watchpoint */ +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); +- +- LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR +- " mask %08" PRIx32, wp_num, wp->address, wp->mask); +- wp_num++; +- } else if (nds32_v3m->nds32.global_stop) { +- clean_global_stop = true; +- } +- } +- +- if (clean_global_stop) { +- uint32_t edm_ctl; +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); +- edm_ctl = edm_ctl & (~0x30); +- aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_check_interrupt_stack(struct nds32 *nds32) +-{ +- uint32_t val_ir0; +- uint32_t value; +- +- /* Save interrupt level */ +- nds32_get_mapped_reg(nds32, IR0, &val_ir0); +- nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; +- +- if (nds32_reach_max_interrupt_level(nds32)) +- LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", +- nds32->current_interrupt_level); +- +- /* backup $ir6 to avoid suppressed exception overwrite */ +- nds32_get_mapped_reg(nds32, IR6, &value); +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_restore_interrupt_stack(struct nds32 *nds32) +-{ +- uint32_t value; +- +- /* get backup value from cache */ +- /* then set back to make the register dirty */ +- nds32_get_mapped_reg(nds32, IR0, &value); +- nds32_set_mapped_reg(nds32, IR0, value); +- +- nds32_get_mapped_reg(nds32, IR6, &value); +- nds32_set_mapped_reg(nds32, IR6, value); +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_deassert_reset(struct target *target) +-{ +- int retval; +- +- CHECK_RETVAL(nds32_poll(target)); +- +- if (target->state != TARGET_HALTED) { +- /* reset only */ +- LOG_WARNING("%s: ran after reset and before halt ...", +- target_name(target)); +- retval = target_halt(target); +- if (retval != ERROR_OK) +- return retval; +- +- } +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_add_breakpoint(struct target *target, +- struct breakpoint *breakpoint) +-{ +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- struct nds32 *nds32 = &(nds32_v3m->nds32); +- int result; +- +- if (breakpoint->type == BKPT_HARD) { +- /* check hardware resource */ +- if (nds32_v3m->next_hbr_index < nds32_v3m->next_hwp_index) { +- LOG_WARNING("<-- TARGET WARNING! Insert too many " +- "hardware breakpoints/watchpoints! " +- "The limit of combined hardware " +- "breakpoints/watchpoints is %" PRId32 ". -->", +- nds32_v3m->n_hbr); +- LOG_WARNING("<-- TARGET STATUS: Inserted number of " +- "hardware breakpoint: %" PRId32 ", hardware " +- "watchpoints: %" PRId32 ". -->", +- nds32_v3m->n_hbr - nds32_v3m->next_hbr_index - 1, +- nds32_v3m->used_n_wp); +- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; +- } +- +- /* update next place to put hardware breakpoint */ +- nds32_v3m->next_hbr_index--; +- +- /* hardware breakpoint insertion occurs before 'continue' actually */ +- return ERROR_OK; +- } else if (breakpoint->type == BKPT_SOFT) { +- result = nds32_add_software_breakpoint(target, breakpoint); +- if (result != ERROR_OK) { +- /* auto convert to hardware breakpoint if failed */ +- if (nds32->auto_convert_hw_bp) { +- /* convert to hardware breakpoint */ +- breakpoint->type = BKPT_HARD; +- +- return nds32_v3m_add_breakpoint(target, breakpoint); +- } +- } +- +- return result; +- } else /* unrecognized breakpoint type */ +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_remove_breakpoint(struct target *target, +- struct breakpoint *breakpoint) +-{ +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- +- if (breakpoint->type == BKPT_HARD) { +- if (nds32_v3m->next_hbr_index >= nds32_v3m->n_hbr - 1) +- return ERROR_FAIL; +- +- /* update next place to put hardware breakpoint */ +- nds32_v3m->next_hbr_index++; +- +- /* hardware breakpoint removal occurs after 'halted' actually */ +- return ERROR_OK; +- } else if (breakpoint->type == BKPT_SOFT) { +- return nds32_remove_software_breakpoint(target, breakpoint); +- } else /* unrecognized breakpoint type */ +- return ERROR_FAIL; +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_add_watchpoint(struct target *target, +- struct watchpoint *watchpoint) +-{ +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- +- /* check hardware resource */ +- if (nds32_v3m->next_hwp_index >= nds32_v3m->n_hwp) { +- /* No hardware resource */ +- if (nds32_v3m->nds32.global_stop) { +- LOG_WARNING("<-- TARGET WARNING! The number of " +- "watchpoints exceeds the hardware " +- "resources. Stop at every load/store " +- "instruction to check for watchpoint matches. -->"); +- return ERROR_OK; +- } +- +- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " +- "watchpoints! The limit of hardware watchpoints " +- "is %" PRId32 ". -->", nds32_v3m->n_hwp); +- LOG_WARNING("<-- TARGET STATUS: Inserted number of " +- "hardware watchpoint: %" PRId32 ". -->", +- nds32_v3m->used_n_wp); +- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; +- } +- +- if (nds32_v3m->next_hwp_index > nds32_v3m->next_hbr_index) { +- /* No hardware resource */ +- if (nds32_v3m->nds32.global_stop) { +- LOG_WARNING("<-- TARGET WARNING! The number of " +- "watchpoints exceeds the hardware " +- "resources. Stop at every load/store " +- "instruction to check for watchpoint matches. -->"); +- return ERROR_OK; +- } +- +- LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " +- "breakpoints/watchpoints! The limit of combined " +- "hardware breakpoints/watchpoints is %" PRId32 ". -->", +- nds32_v3m->n_hbr); +- LOG_WARNING("<-- TARGET STATUS: Inserted number of " +- "hardware breakpoint: %" PRId32 ", hardware " +- "watchpoints: %" PRId32 ". -->", +- nds32_v3m->n_hbr - nds32_v3m->next_hbr_index - 1, +- nds32_v3m->used_n_wp); +- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; +- } +- +- /* update next place to put hardware watchpoint */ +- nds32_v3m->next_hwp_index++; +- nds32_v3m->used_n_wp++; +- +- return ERROR_OK; +-} +- +-static int nds32_v3m_remove_watchpoint(struct target *target, +- struct watchpoint *watchpoint) +-{ +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- +- if (nds32_v3m->next_hwp_index <= 0) { +- if (nds32_v3m->nds32.global_stop) +- return ERROR_OK; +- +- return ERROR_FAIL; +- } +- +- /* update next place to put hardware watchpoint */ +- nds32_v3m->next_hwp_index--; +- nds32_v3m->used_n_wp--; +- +- return ERROR_OK; +-} +- +-static struct nds32_v3_common_callback nds32_v3m_common_callback = { +- .check_interrupt_stack = nds32_v3m_check_interrupt_stack, +- .restore_interrupt_stack = nds32_v3m_restore_interrupt_stack, +- .activate_hardware_breakpoint = nds32_v3m_activate_hardware_breakpoint, +- .activate_hardware_watchpoint = nds32_v3m_activate_hardware_watchpoint, +- .deactivate_hardware_breakpoint = nds32_v3m_deactivate_hardware_breakpoint, +- .deactivate_hardware_watchpoint = nds32_v3m_deactivate_hardware_watchpoint, +-}; +- +-static int nds32_v3m_target_create(struct target *target, Jim_Interp *interp) +-{ +- struct nds32_v3m_common *nds32_v3m; +- +- nds32_v3m = calloc(1, sizeof(*nds32_v3m)); +- if (!nds32_v3m) +- return ERROR_FAIL; +- +- nds32_v3_common_register_callback(&nds32_v3m_common_callback); +- nds32_v3_target_create_common(target, &(nds32_v3m->nds32)); +- +- return ERROR_OK; +-} +- +-/* talk to the target and set things up */ +-static int nds32_v3m_examine(struct target *target) +-{ +- struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); +- struct nds32 *nds32 = &(nds32_v3m->nds32); +- struct aice_port_s *aice = target_to_aice(target); +- +- if (!target_was_examined(target)) { +- CHECK_RETVAL(nds32_edm_config(nds32)); +- +- if (nds32->reset_halt_as_examine) +- CHECK_RETVAL(nds32_reset_halt(nds32)); +- } +- +- uint32_t edm_cfg; +- aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); +- +- /* get the number of hardware breakpoints */ +- nds32_v3m->n_hbr = (edm_cfg & 0x7) + 1; +- nds32_v3m->used_n_wp = 0; +- +- /* get the number of hardware watchpoints */ +- /* If the WP field is hardwired to zero, it means this is a +- * simple breakpoint. Otherwise, if the WP field is writable +- * then it means this is a regular watchpoints. */ +- nds32_v3m->n_hwp = 0; +- for (int32_t i = 0 ; i < nds32_v3m->n_hbr ; i++) { +- /** check the hardware breakpoint is simple or not */ +- uint32_t tmp_value; +- aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + i, 0x1); +- aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &tmp_value); +- +- if (tmp_value) +- nds32_v3m->n_hwp++; +- } +- /* hardware breakpoint is inserted from high index to low index */ +- nds32_v3m->next_hbr_index = nds32_v3m->n_hbr - 1; +- /* hardware watchpoint is inserted from low index to high index */ +- nds32_v3m->next_hwp_index = 0; +- +- LOG_INFO("%s: total hardware breakpoint %" PRId32 " (simple breakpoint %" PRId32 ")", +- target_name(target), nds32_v3m->n_hbr, nds32_v3m->n_hbr - nds32_v3m->n_hwp); +- LOG_INFO("%s: total hardware watchpoint %" PRId32, target_name(target), nds32_v3m->n_hwp); +- +- nds32->target->state = TARGET_RUNNING; +- nds32->target->debug_reason = DBG_REASON_NOTHALTED; +- +- target_set_examined(target); +- +- return ERROR_OK; +-} +- +-/** Holds methods for NDS32 V3m targets. */ +-struct target_type nds32_v3m_target = { +- .name = "nds32_v3m", +- +- .poll = nds32_poll, +- .arch_state = nds32_arch_state, +- +- .target_request_data = nds32_v3_target_request_data, +- +- .halt = nds32_halt, +- .resume = nds32_resume, +- .step = nds32_step, +- +- .assert_reset = nds32_assert_reset, +- .deassert_reset = nds32_v3m_deassert_reset, +- +- /* register access */ +- .get_gdb_reg_list = nds32_get_gdb_reg_list, +- +- /* memory access */ +- .read_buffer = nds32_v3_read_buffer, +- .write_buffer = nds32_v3_write_buffer, +- .read_memory = nds32_v3_read_memory, +- .write_memory = nds32_v3_write_memory, +- +- .checksum_memory = nds32_v3_checksum_memory, +- +- /* breakpoint/watchpoint */ +- .add_breakpoint = nds32_v3m_add_breakpoint, +- .remove_breakpoint = nds32_v3m_remove_breakpoint, +- .add_watchpoint = nds32_v3m_add_watchpoint, +- .remove_watchpoint = nds32_v3m_remove_watchpoint, +- .hit_watchpoint = nds32_v3_hit_watchpoint, +- +- /* MMU */ +- .mmu = nds32_mmu, +- .virt2phys = nds32_virtual_to_physical, +- .read_phys_memory = nds32_read_phys_memory, +- .write_phys_memory = nds32_write_phys_memory, +- +- .run_algorithm = nds32_v3_run_algorithm, +- +- .commands = nds32_command_handlers, +- .target_create = nds32_v3m_target_create, +- .init_target = nds32_v3_init_target, +- .examine = nds32_v3m_examine, +- +- .get_gdb_fileio_info = nds32_get_gdb_fileio_info, +- .gdb_fileio_end = nds32_gdb_fileio_end, +-}; +diff --git a/src/target/nds32_v3m.h b/src/target/nds32_v3m.h +deleted file mode 100644 +index f21dd62c5..000000000 +--- a/src/target/nds32_v3m.h ++++ /dev/null +@@ -1,40 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2013 Andes Technology * +- * Hsiangkai Wang * +- ***************************************************************************/ +- +-#ifndef OPENOCD_TARGET_NDS32_V3M_H +-#define OPENOCD_TARGET_NDS32_V3M_H +- +-#include "nds32.h" +- +-struct nds32_v3m_common { +- struct nds32 nds32; +- +- /** number of hardware breakpoints */ +- int32_t n_hbr; +- +- /** number of hardware watchpoints */ +- int32_t n_hwp; +- +- /** number of used hardware watchpoints */ +- int32_t used_n_wp; +- +- /** next hardware breakpoint index */ +- /** for simple breakpoints, hardware breakpoints are inserted +- * from high index to low index */ +- int32_t next_hbr_index; +- +- /** next hardware watchpoint index */ +- /** increase from low index to high index */ +- int32_t next_hwp_index; +-}; +- +-static inline struct nds32_v3m_common *target_to_nds32_v3m(struct target *target) +-{ +- return container_of(target->arch_info, struct nds32_v3m_common, nds32); +-} +- +-#endif /* OPENOCD_TARGET_NDS32_V3M_H */ +diff --git a/src/target/target.c b/src/target/target.c +index e3a6f955e..ae419ac8b 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -92,9 +92,6 @@ extern struct target_type dsp5680xx_target; + extern struct target_type testee_target; + extern struct target_type avr32_ap7k_target; + extern struct target_type hla_target; +-extern struct target_type nds32_v2_target; +-extern struct target_type nds32_v3_target; +-extern struct target_type nds32_v3m_target; + extern struct target_type esp32_target; + extern struct target_type esp32s2_target; + extern struct target_type esp32s3_target; +@@ -132,9 +129,6 @@ static struct target_type *target_types[] = { + &testee_target, + &avr32_ap7k_target, + &hla_target, +- &nds32_v2_target, +- &nds32_v3_target, +- &nds32_v3m_target, + &esp32_target, + &esp32s2_target, + &esp32s3_target, +diff --git a/tcl/board/nds32_xc5.cfg b/tcl/board/nds32_xc5.cfg +deleted file mode 100644 +index 82a117e71..000000000 +--- a/tcl/board/nds32_xc5.cfg ++++ /dev/null +@@ -1,7 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-set _CPUTAPID 0x1000063d +-set _CHIPNAME nds32 +-source [find target/nds32v3.cfg] +- +-jtag init +diff --git a/tcl/interface/nds32-aice.cfg b/tcl/interface/nds32-aice.cfg +deleted file mode 100644 +index 1d9717c4c..000000000 +--- a/tcl/interface/nds32-aice.cfg ++++ /dev/null +@@ -1,17 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-# +-# Andes AICE +-# +-# http://www.andestech.com +-# +- +-adapter driver aice +-aice desc "Andes AICE adapter" +-# adapter serial "C001-42163" +-aice vid_pid 0x1CFC 0x0000 +-aice port aice_usb +-reset_config trst_and_srst +-adapter speed 24000 +-aice retry_times 50 +-aice count_to_check_dbger 30 +diff --git a/tcl/target/nds32v2.cfg b/tcl/target/nds32v2.cfg +deleted file mode 100644 +index 07814b7f3..000000000 +--- a/tcl/target/nds32v2.cfg ++++ /dev/null +@@ -1,12 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-# +-# Andes Core +-# +-# http://www.andestech.com +-# +- +-jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID +- +-set _TARGETNAME $_CHIPNAME.cpu +-target create $_TARGETNAME nds32_v2 -endian little -chain-position $_TARGETNAME +diff --git a/tcl/target/nds32v3.cfg b/tcl/target/nds32v3.cfg +deleted file mode 100644 +index 0fd136910..000000000 +--- a/tcl/target/nds32v3.cfg ++++ /dev/null +@@ -1,12 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-# +-# Andes Core +-# +-# http://www.andestech.com +-# +- +-jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID +- +-set _TARGETNAME $_CHIPNAME.cpu +-target create $_TARGETNAME nds32_v3 -endian little -chain-position $_TARGETNAME +diff --git a/tcl/target/nds32v3m.cfg b/tcl/target/nds32v3m.cfg +deleted file mode 100644 +index 29a247805..000000000 +--- a/tcl/target/nds32v3m.cfg ++++ /dev/null +@@ -1,12 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-# +-# Andes Core +-# +-# http://www.andestech.com +-# +- +-jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID +- +-set _TARGETNAME $_CHIPNAME.cpu +-target create $_TARGETNAME nds32_v3m -endian little -chain-position $_TARGETNAME +diff --git a/tools/scripts/camelcase.txt b/tools/scripts/camelcase.txt +index 59fe5cae0..2caa81caa 100644 +--- a/tools/scripts/camelcase.txt ++++ b/tools/scripts/camelcase.txt +@@ -175,10 +175,7 @@ __FreeBSD_kernel__ + # for Windows + CreateFile + CloseHandle +-CreatePipe +-CreateProcess + FormatMessage +-GetLastError + GetModuleFileName + GetSystemTimeAsFileTime + GetTickCount +@@ -189,29 +186,16 @@ MsgWaitForMultipleObjects + PeekMessage + PeekNamedPipe + QuadPart +-ReadFile + SetConsoleCtrlHandler +-SetHandleInformation + Sleep + WaitForSingleObject +-WriteFile + WSACleanup + WSAGetLastError + WSAStartup +-ZeroMemory +-bInheritHandle +-dwFlags + dwHighDateTime + dwLowDateTime + dwPlatformId + dwOSVersionInfoSize +-hProcess +-hThread +-hStdError +-hStdInput +-hStdOutput +-lpSecurityDescriptor +-nLength + + # OpenOCD exceptions that should be removed + KiB diff --git a/meta-oe/recipes-devtools/openocd/openocd/0004-openocd-revert-workarounds-for-expr-syntax-change.patch b/meta-oe/recipes-devtools/openocd/openocd/0004-openocd-revert-workarounds-for-expr-syntax-change.patch new file mode 100644 index 000000000..766790bf1 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0004-openocd-revert-workarounds-for-expr-syntax-change.patch @@ -0,0 +1,127 @@ +From 95603fae18f81eebdafc5b318e70f9e2cdefab9e Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 18 Dec 2022 19:15:57 +0100 +Subject: [PATCH] openocd: revert workarounds for 'expr' syntax change + +With OpenOCD v0.12.0 released, drop the workarounds for 'expr' +syntax change by reverting: +- commit 320043c054dc ("openocd: fix for polling during "expr" + computation"); +- commit c7eaaf620488 ("openocd: prepare for jimtcl 0.81 'expr' + syntax change"). + +Replace the call to target_call_timer_callbacks_now() with call +to target_call_timer_callbacks(). + +Change-Id: Iae5afc50e3f688e11176a52648efc9a6577a9a11 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7405 +Tested-by: jenkins +--- + src/helper/command.c | 14 +---------- + src/openocd.c | 60 -------------------------------------------- + 2 files changed, 1 insertion(+), 73 deletions(-) + +diff --git a/src/helper/command.c b/src/helper/command.c +index 6898e2d7c..ca66cf7dd 100644 +--- a/src/helper/command.c ++++ b/src/helper/command.c +@@ -936,19 +936,7 @@ static int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *a + if (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL))) + return JIM_ERR; + +- /* +- * TODO: to be removed after v0.12.0 +- * workaround for https://sourceforge.net/p/openocd/tickets/362/ +- * After syntax change of "expr" in jimtcl 0.81 +- * the replacement of jimtcl "expr" with openocd version in +- * https://review.openocd.org/6510/ +- * introduces too many target polling during math expressions with +- * "expr" commands. +- * After v0.12.0 replace the following two lines with +- * target_call_timer_callbacks(); +- */ +- if (strcmp(c->name, "expr")) +- target_call_timer_callbacks_now(); ++ target_call_timer_callbacks(); + + /* + * Black magic of overridden current target: +diff --git a/src/openocd.c b/src/openocd.c +index bef084f98..875da5a62 100644 +--- a/src/openocd.c ++++ b/src/openocd.c +@@ -230,65 +230,6 @@ static int openocd_register_commands(struct command_context *cmd_ctx) + return register_commands(cmd_ctx, NULL, openocd_command_handlers); + } + +-/* +- * TODO: to be removed after v0.12.0 +- * workaround for syntax change of "expr" in jimtcl 0.81 +- * replace "expr" with openocd version that prints the deprecated msg +- */ +-struct jim_scriptobj { +- void *token; +- Jim_Obj *filename_obj; +- int len; +- int subst_flags; +- int in_use; +- int firstline; +- int linenr; +- int missing; +-}; +- +-static int jim_expr_command(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- if (argc == 2) +- return Jim_EvalExpression(interp, argv[1]); +- +- if (argc > 2) { +- Jim_Obj *obj = Jim_ConcatObj(interp, argc - 1, argv + 1); +- Jim_IncrRefCount(obj); +- const char *s = Jim_String(obj); +- struct jim_scriptobj *script = Jim_GetIntRepPtr(interp->currentScriptObj); +- if (interp->currentScriptObj == interp->emptyObj || +- strcmp(interp->currentScriptObj->typePtr->name, "script") || +- script->subst_flags || +- script->filename_obj == interp->emptyObj) +- LOG_WARNING("DEPRECATED! use 'expr { %s }' not 'expr %s'", s, s); +- else +- LOG_WARNING("DEPRECATED! (%s:%d) use 'expr { %s }' not 'expr %s'", +- Jim_String(script->filename_obj), script->linenr, s, s); +- int retcode = Jim_EvalExpression(interp, obj); +- Jim_DecrRefCount(interp, obj); +- return retcode; +- } +- +- Jim_WrongNumArgs(interp, 1, argv, "expression ?...?"); +- return JIM_ERR; +-} +- +-static const struct command_registration expr_handler[] = { +- { +- .name = "expr", +- .jim_handler = jim_expr_command, +- .mode = COMMAND_ANY, +- .help = "", +- .usage = "", +- }, +- COMMAND_REGISTRATION_DONE +-}; +- +-static int workaround_for_jimtcl_expr(struct command_context *cmd_ctx) +-{ +- return register_commands(cmd_ctx, NULL, expr_handler); +-} +- + struct command_context *global_cmd_ctx; + + static struct command_context *setup_command_handler(Jim_Interp *interp) +@@ -301,7 +242,6 @@ static struct command_context *setup_command_handler(Jim_Interp *interp) + /* register subsystem commands */ + typedef int (*command_registrant_t)(struct command_context *cmd_ctx_value); + static const command_registrant_t command_registrants[] = { +- &workaround_for_jimtcl_expr, + &openocd_register_commands, + &server_register_commands, + &gdb_register_commands, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0005-flash-nor-avrf-add-ATmega32U4-support.patch b/meta-oe/recipes-devtools/openocd/openocd/0005-flash-nor-avrf-add-ATmega32U4-support.patch new file mode 100644 index 000000000..0473d29bc --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0005-flash-nor-avrf-add-ATmega32U4-support.patch @@ -0,0 +1,66 @@ +From 0c28006cf2cf2d98ba2d73a73bf629e781f4ffb8 Mon Sep 17 00:00:00 2001 +From: Kyle Schwarz +Date: Sun, 10 Jul 2022 15:58:14 -0400 +Subject: [PATCH] flash/nor/avrf: add ATmega32U4 support + +Add new chip info and tcl target + +Change-Id: Ib9d33d1b145a8659857b7a6cc9c5acba047f41d1 +Signed-off-by: Kyle Schwarz +Reviewed-on: https://review.openocd.org/c/openocd/+/7081 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/avrf.c | 1 + + tcl/target/atmega32u4.cfg | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 31 insertions(+) + create mode 100644 tcl/target/atmega32u4.cfg + +diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c +index 0e2e263ce..1d317a10c 100644 +--- a/src/flash/nor/avrf.c ++++ b/src/flash/nor/avrf.c +@@ -64,6 +64,7 @@ static const struct avrf_type avft_chips_info[] = { + {"atmega324pa", 0x9511, 128, 256, 4, 256}, + {"atmega644p", 0x960a, 256, 256, 8, 256}, + {"atmega1284p", 0x9705, 256, 512, 8, 512}, ++ {"atmega32u4", 0x9587, 128, 256, 4, 256}, + }; + + /* avr program functions */ +diff --git a/tcl/target/atmega32u4.cfg b/tcl/target/atmega32u4.cfg +new file mode 100644 +index 000000000..9199c741e +--- /dev/null ++++ b/tcl/target/atmega32u4.cfg +@@ -0,0 +1,30 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ATmega32U4 ++ ++if { [info exists CHIPNAME] } { ++ set _CHIPNAME $CHIPNAME ++} else { ++ set _CHIPNAME avr ++} ++ ++if { [info exists ENDIAN] } { ++ set _ENDIAN $ENDIAN ++} else { ++ set _ENDIAN little ++} ++ ++if { [info exists CPUTAPID] } { ++ set _CPUTAPID $CPUTAPID ++} else { ++ set _CPUTAPID 0x4958703f ++} ++ ++adapter speed 4500 ++ ++jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID ++ ++set _TARGETNAME $_CHIPNAME.cpu ++target create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME ++ ++set _FLASHNAME $_CHIPNAME.flash ++flash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME diff --git a/meta-oe/recipes-devtools/openocd/openocd/0006-target-xtensa-remove-needless-target_was_examined-ch.patch b/meta-oe/recipes-devtools/openocd/openocd/0006-target-xtensa-remove-needless-target_was_examined-ch.patch new file mode 100644 index 000000000..1fcbd580a --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0006-target-xtensa-remove-needless-target_was_examined-ch.patch @@ -0,0 +1,31 @@ +From 0708ccead4fbce07e3d78bb7380aca0aae8cb14d Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Thu, 29 Sep 2022 00:22:00 +0200 +Subject: [PATCH] target/xtensa: remove needless target_was_examined check + +In any case flag will be set as examined. + +Signed-off-by: Erhan Kurubas +Change-Id: I5177ee656f726a807269e2f4725223f50e49e855 +Reviewed-on: https://review.openocd.org/c/openocd/+/7231 +Tested-by: jenkins +Reviewed-by: Ian Thompson +Reviewed-by: Antonio Borneo +--- + src/target/xtensa/xtensa.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c +index c2c047edb..b57e2d660 100644 +--- a/src/target/xtensa/xtensa.c ++++ b/src/target/xtensa/xtensa.c +@@ -801,8 +801,7 @@ int xtensa_examine(struct target *target) + return ERROR_TARGET_FAILURE; + } + LOG_DEBUG("OCD_ID = %08" PRIx32, xtensa->dbg_mod.device_id); +- if (!target_was_examined(target)) +- target_set_examined(target); ++ target_set_examined(target); + xtensa_smpbreak_write(xtensa, xtensa->smp_break); + return ERROR_OK; + } diff --git a/meta-oe/recipes-devtools/openocd/openocd/0007-flash-nor-spi-Add-issi-is25lq040b-to-device-list.patch b/meta-oe/recipes-devtools/openocd/openocd/0007-flash-nor-spi-Add-issi-is25lq040b-to-device-list.patch new file mode 100644 index 000000000..587a66a86 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0007-flash-nor-spi-Add-issi-is25lq040b-to-device-list.patch @@ -0,0 +1,30 @@ +From 9a7781ff8c9dea6ef5998238b1932094b8a226da Mon Sep 17 00:00:00 2001 +From: Fawaz Tirmizi +Date: Fri, 19 Aug 2022 14:22:06 -0700 +Subject: [PATCH] flash/nor/spi: Add issi is25lq040b to device list + +The HiFive Inventor uses this flash chip, so adding it will allow for +openocd to be used to program it. These values were taken from the +chip's documentation. + +Signed-off-by: Fawaz Tirmizi +Change-Id: I15c9d35f99d4500f73134cdc2d1b9ab6279b491c +Reviewed-on: https://review.openocd.org/c/openocd/+/7135 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/spi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c +index eed747b58..373a9a144 100644 +--- a/src/flash/nor/spi.c ++++ b/src/flash/nor/spi.c +@@ -112,6 +112,7 @@ const struct flash_device flash_devices[] = { + FLASH_ID("gd gd25q128c", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001840c8, 0x100, 0x10000, 0x1000000), + FLASH_ID("gd gd25q256c", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x001940c8, 0x100, 0x10000, 0x2000000), + FLASH_ID("gd gd25q512mc", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x002040c8, 0x100, 0x10000, 0x4000000), ++ FLASH_ID("issi is25lq040b", 0x03, 0xeb, 0x02, 0x20, 0xc7, 0x0013409d, 0x100, 0x1000, 0x80000), + FLASH_ID("issi is25lp032", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0016609d, 0x100, 0x10000, 0x400000), + FLASH_ID("issi is25lp064", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0017609d, 0x100, 0x10000, 0x800000), + FLASH_ID("issi is25lp128d", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0018609d, 0x100, 0x10000, 0x1000000), diff --git a/meta-oe/recipes-devtools/openocd/openocd/0008-src-rtos-eCos-Support-per-build-configuration-specif.patch b/meta-oe/recipes-devtools/openocd/openocd/0008-src-rtos-eCos-Support-per-build-configuration-specif.patch new file mode 100644 index 000000000..f64a45b97 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0008-src-rtos-eCos-Support-per-build-configuration-specif.patch @@ -0,0 +1,1295 @@ +From d96dc47ef67e427cd64a07d9825fd297e3a81633 Mon Sep 17 00:00:00 2001 +From: "James G. Smith" +Date: Wed, 26 May 2021 10:08:26 +0100 +Subject: [PATCH] src/rtos/eCos : Support per-build configuration specific + structure layouts + +Extended feature. This is a large patch, but is self-contained to the +eCos support and does not affect any other openocd functionality. It +does NOT affect existing eCos RTOS plugin users where their +applications do not provide the extended symbolic helper +information. If the helper symbols are not available the rtos support +code will behave as before. This "dynamic" functionality is *required* +because eCos does NOT have a fixed/hardwired, known, layout for the +thread descriptor structure. The per-application build eCos +configuration can affect the shape of the thread descriptor structure +(field presence, and hence offsets of subsequent fields) such that +constant values cannot be used to consistently interpret all possible +eCos application configurations. For historical reasons, there is not +yet a consistent namespace for the helper symbols across eCos HALs +hence the support is currently limited to specific architectures +(Cortex-M and ARM/Cortex-A). No new Clang analyser warnings are raised +by this changeset. + +Change-Id: Ib3a36877326eeb56595cbca55e21b9e59a59c98a +Signed-off-by: James G. Smith +Reviewed-on: https://review.openocd.org/c/openocd/+/6275 +Reviewed-by: Alex Schuilenburg +Reviewed-by: Antonio Borneo +Tested-by: jenkins +--- + src/rtos/eCos.c | 1033 +++++++++++++++++++++++++++++--- + src/rtos/rtos_ecos_stackings.c | 7 + + 2 files changed, 950 insertions(+), 90 deletions(-) + +diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c +index 3f813ac38..963bb61cf 100644 +--- a/src/rtos/eCos.c ++++ b/src/rtos/eCos.c +@@ -11,66 +11,446 @@ + #include + #include "target/target.h" + #include "target/target_type.h" ++#include "target/armv7m.h" + #include "rtos.h" + #include "helper/log.h" + #include "helper/types.h" ++#include "helper/bits.h" ++#include "rtos_standard_stackings.h" + #include "rtos_ecos_stackings.h" ++#include "server/gdb_server.h" ++ ++/* Unfortunately for the moment we are limited to returning the hardwired ++ * register count (ARMV7M_NUM_CORE_REGS for Cortex-M) since the openocd RTOS ++ * support does not yet support accessing all per-thread "stacked" ++ * registers. e.g. For Cortex-M under eCos we have a per-thread BASEPRI, and for ++ * all eCos targets we may have per-thread VFP/FPU register state. ++ * ++ * So, for the moment, we continue to use the hardwired limit for the depth of ++ * the returned register description vector. The current openocd ++ * rtos_standard_stackings.c just provides the main core regs for the Cortex_M* ++ * targets regardless of whether FPU is present/enabled. ++ * ++ * However, this code is written with the expectation that we may eventually be ++ * able to provide more register information ("m-system" and "vfp" for example) ++ * and also with the expectation of supporting different register sets being ++ * returned depending on the per-thread Cortex-M eCos contex_m for ++ * example. Hence the fact that the eCos_stack_layout_*() functions below allow ++ * for the stack context descriptor vector to be returned by those calls ++ * allowing for eventual support where this code will potentially cache ++ * different sets of register descriptors for the different shapes of contexts ++ * in a *single* application/binary run-time. ++ * ++ * TODO: Extend openocd generic RTOS support to allow thread-specific system and ++ * FPU register state to be returned. */ ++ ++struct ecos_params; + + static bool ecos_detect_rtos(struct target *target); + static int ecos_create(struct target *target); + static int ecos_update_threads(struct rtos *rtos); + static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs); + static int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]); ++static int ecos_stack_layout_cortexm(struct rtos *rtos, struct ecos_params *param, ++ int64_t stack_ptr, const struct rtos_register_stacking **si); ++static int ecos_stack_layout_arm(struct rtos *rtos, struct ecos_params *param, ++ int64_t stack_ptr, const struct rtos_register_stacking **si); ++ ++/* The current eCos thread IDentifier uses 0 as an unused (not a valid thread ++ * ID) value. Currently the unique_id field is 16-bits, but the eCos SMP support ++ * convention is that only 12-bits of the ID will be used. This ++ * ECOS_MAX_THREAD_COUNT manifest is provided to limit the potential for ++ * interpreting stale/inconsistent thread list state when the debug host scans ++ * the thread list before the target RTOS has completed its initialisation. This ++ * support will need to revisited when eCos is re-engineered to support more ++ * than 16 CPU SMP setups. */ ++#define ECOS_MAX_THREAD_COUNT (4095) + + struct ecos_thread_state { + int value; + const char *desc; + }; + +-static const struct ecos_thread_state ecos_thread_states[] = { +- { 0, "Ready" }, +- { 1, "Sleeping" }, +- { 2, "Countsleep" }, +- { 4, "Suspended" }, +- { 8, "Creating" }, +- { 16, "Exited" } ++/* The status is actually a logical-OR bitmask of states: */ ++enum ecos_thread_state_flags { ++ RUNNING = 0, /* explicit no-bits-set value */ ++ SLEEPING = BIT(0), ++ COUNTSLEEP = BIT(1), ++ SUSPENDED = BIT(2), ++ CREATING = BIT(3), ++ EXITED = BIT(4), ++ SLEEPSET = (SLEEPING | COUNTSLEEP) ++}; ++ ++/* Cyg_Thread:: reason codes for wake and sleep fields: */ ++static const struct ecos_thread_state ecos_thread_reasons[] = { ++ { 0, "NONE" }, /* normally indicates "not yet started" */ ++ { 1, "WAIT" }, /* wait with no timeout */ ++ { 2, "DELAY" }, /* simple time delay */ ++ { 3, "TIMEOUT" }, /* wait with timeout *or* timeout expired */ ++ { 4, "BREAK" }, /* forced break out of sleep */ ++ { 5, "DESTRUCT" }, /* wait on object being destroyed */ ++ { 6, "EXIT" }, /* forced termination */ ++ { 7, "DONE" } /* wait/delay completed */ ++}; ++ ++static const char * const target_cortex_m[] = { ++ "cortex_m", ++ "hla_target", ++ NULL ++}; ++ ++static const char * const target_arm[] = { ++ "cortex_a", ++ "arm7tdmi", ++ "arm720t", ++ "arm9tdmi", ++ "arm920t", ++ "arm926ejs", ++ "arm946e", ++ "arm966e", ++ "arm11", ++ NULL + }; + +-#define ECOS_NUM_STATES ARRAY_SIZE(ecos_thread_states) ++/* Since individual eCos application configurations may have different thread ++ * object structure layouts depending on the actual build-time enabled features ++ * we provide support for applications built containing the relevant symbolic ++ * support to match the actual application binary being debugged, rather than ++ * relying on a set of default/fixed (and potentially incorrect) ++ * offsets. However, for backwards compatibility, we do *NOT* enforce the ++ * requirement for the common extra helper symbols to be present to allow the ++ * fallback to the simple fixed CM3 model to avoid affecting existing users of ++ * older eCos worlds. Similarly we need to provide support for per-thread ++ * register context offsets, as well as for per-application-configurations, ++ * since some targets can have different stacked state on a per-thread basis ++ * (e.g. "cortex_m"). This is why the stacking_info is now set at run-time ++ * rather than being fixed. */ + + struct ecos_params { +- const char *target_name; ++ const char * const *target_names; /* NULL terminated list of targets */ ++ int (*target_stack_layout)(struct rtos *rtos, struct ecos_params *param, ++ int64_t stack_ptr, const struct rtos_register_stacking **si); ++ bool flush_common; + unsigned char pointer_width; +- unsigned char thread_stack_offset; +- unsigned char thread_name_offset; +- unsigned char thread_state_offset; +- unsigned char thread_next_offset; +- unsigned char thread_uniqueid_offset; ++ unsigned char uid_width; ++ unsigned char state_width; ++ unsigned int thread_stack_offset; ++ unsigned int thread_name_offset; ++ unsigned int thread_state_offset; ++ unsigned int thread_next_offset; ++ unsigned int thread_uniqueid_offset; + const struct rtos_register_stacking *stacking_info; + }; + +-static const struct ecos_params ecos_params_list[] = { ++/* As mentioned above we provide default offset values for the "cortex_m" ++ * targets for backwards compatibility with older eCos application builds and ++ * previous users of this RTOS specific support that do not have the ++ * configuration specific offsets provided in the symbol table. The support for ++ * other targets (e.g. "cortex_a") we do expect the application to provide the ++ * required symbolic information. We do not populate the stacking_info reference ++ * until we have had a chance to interrogate the symbol table. */ ++ ++static struct ecos_params ecos_params_list[] = { ++ { ++ .target_names = target_cortex_m, ++ .pointer_width = 4, ++ .uid_width = 2, ++ .state_width = 4, ++ .thread_stack_offset = 0x0c, ++ .thread_name_offset = 0x9c, ++ .thread_state_offset = 0x3c, ++ .thread_next_offset = 0xa0, ++ .thread_uniqueid_offset = 0x4c, ++ .target_stack_layout = ecos_stack_layout_cortexm, ++ .stacking_info = NULL ++ }, + { +- "cortex_m", /* target_name */ +- 4, /* pointer_width; */ +- 0x0c, /* thread_stack_offset; */ +- 0x9c, /* thread_name_offset; */ +- 0x3c, /* thread_state_offset; */ +- 0xa0, /* thread_next_offset */ +- 0x4c, /* thread_uniqueid_offset */ +- &rtos_ecos_cortex_m3_stacking /* stacking_info */ ++ .target_names = target_arm, ++ .pointer_width = 0, ++ .uid_width = 0, ++ .state_width = 0, ++ .thread_stack_offset = 0, ++ .thread_name_offset = 0, ++ .thread_state_offset = 0, ++ .thread_next_offset = 0, ++ .thread_uniqueid_offset = 0, ++ .target_stack_layout = ecos_stack_layout_arm, ++ .stacking_info = NULL + } + }; + ++#define ECOS_NUM_PARAMS ARRAY_SIZE(ecos_params_list) ++ ++/* To eventually allow for more than just the ARMV7M_NUM_CORE_REGS to be ++ * returned by the Cortex-M support, and to avoid run-time lookups we manually ++ * maintain our own mapping for the supplied stack register vector entries. This ++ * enum needs to match the rtos_ecos_regoff_cortexm[] vector. Admittedly the ++ * initial indices just match the corresponding ARMV7M_R* definitions, but after ++ * the base registers the ARMV7M_* number space does not match the vector we ++ * wish to populate in this eCos support code. */ ++enum ecos_reglist_cortexm { ++ ECOS_REGLIST_R0 = 0, ++ ECOS_REGLIST_R1, ++ ECOS_REGLIST_R2, ++ ECOS_REGLIST_R3, ++ ECOS_REGLIST_R4, ++ ECOS_REGLIST_R5, ++ ECOS_REGLIST_R6, ++ ECOS_REGLIST_R7, ++ ECOS_REGLIST_R8, ++ ECOS_REGLIST_R9, ++ ECOS_REGLIST_R10, ++ ECOS_REGLIST_R11, ++ ECOS_REGLIST_R12, ++ ECOS_REGLIST_R13, ++ ECOS_REGLIST_R14, ++ ECOS_REGLIST_PC, ++ ECOS_REGLIST_XPSR, /* ARMV7M_NUM_CORE_REGS */ ++ ECOS_REGLIST_BASEPRI, ++ ECOS_REGLIST_FPSCR, /* Following for FPU contexts */ ++ ECOS_REGLIST_D0, ++ ECOS_REGLIST_D1, ++ ECOS_REGLIST_D2, ++ ECOS_REGLIST_D3, ++ ECOS_REGLIST_D4, ++ ECOS_REGLIST_D5, ++ ECOS_REGLIST_D6, ++ ECOS_REGLIST_D7, ++ ECOS_REGLIST_D8, ++ ECOS_REGLIST_D9, ++ ECOS_REGLIST_D10, ++ ECOS_REGLIST_D11, ++ ECOS_REGLIST_D12, ++ ECOS_REGLIST_D13, ++ ECOS_REGLIST_D14, ++ ECOS_REGLIST_D15 ++}; ++ ++#define ECOS_CORTEXM_BASE_NUMREGS (ARMV7M_NUM_CORE_REGS) ++ ++/* NOTE: The offsets in this vector are overwritten by the architecture specific ++ * layout functions depending on the specific application configuration. The ++ * ordering of this vector MUST match eCos_reglist. */ ++static struct stack_register_offset rtos_ecos_regoff_cortexm[] = { ++ { ARMV7M_R0, -1, 32 }, /* r0 */ ++ { ARMV7M_R1, -1, 32 }, /* r1 */ ++ { ARMV7M_R2, -1, 32 }, /* r2 */ ++ { ARMV7M_R3, -1, 32 }, /* r3 */ ++ { ARMV7M_R4, -1, 32 }, /* r4 */ ++ { ARMV7M_R5, -1, 32 }, /* r5 */ ++ { ARMV7M_R6, -1, 32 }, /* r6 */ ++ { ARMV7M_R7, -1, 32 }, /* r7 */ ++ { ARMV7M_R8, -1, 32 }, /* r8 */ ++ { ARMV7M_R9, -1, 32 }, /* r9 */ ++ { ARMV7M_R10, -1, 32 }, /* r10 */ ++ { ARMV7M_R11, -1, 32 }, /* r11 */ ++ { ARMV7M_R12, -1, 32 }, /* r12 */ ++ { ARMV7M_R13, -1, 32 }, /* sp */ ++ { ARMV7M_R14, -1, 32 }, /* lr */ ++ { ARMV7M_PC, -1, 32 }, /* pc */ ++ { ARMV7M_XPSR, -1, 32 }, /* xPSR */ ++ { ARMV7M_BASEPRI, -1, 32 }, /* BASEPRI */ ++ { ARMV7M_FPSCR, -1, 32 }, /* FPSCR */ ++ { ARMV7M_D0, -1, 64 }, /* D0 (S0/S1) */ ++ { ARMV7M_D1, -1, 64 }, /* D1 (S2/S3) */ ++ { ARMV7M_D2, -1, 64 }, /* D2 (S4/S5) */ ++ { ARMV7M_D3, -1, 64 }, /* D3 (S6/S7) */ ++ { ARMV7M_D4, -1, 64 }, /* D4 (S8/S9) */ ++ { ARMV7M_D5, -1, 64 }, /* D5 (S10/S11) */ ++ { ARMV7M_D6, -1, 64 }, /* D6 (S12/S13) */ ++ { ARMV7M_D7, -1, 64 }, /* D7 (S14/S15) */ ++ { ARMV7M_D8, -1, 64 }, /* D8 (S16/S17) */ ++ { ARMV7M_D9, -1, 64 }, /* D9 (S18/S19) */ ++ { ARMV7M_D10, -1, 64 }, /* D10 (S20/S21) */ ++ { ARMV7M_D11, -1, 64 }, /* D11 (S22/S23) */ ++ { ARMV7M_D12, -1, 64 }, /* D12 (S24/S25) */ ++ { ARMV7M_D13, -1, 64 }, /* D13 (S26/S27) */ ++ { ARMV7M_D14, -1, 64 }, /* D14 (S28/S29) */ ++ { ARMV7M_D15, -1, 64 }, /* D15 (S30/S31) */ ++}; ++ ++static struct stack_register_offset rtos_ecos_regoff_arm[] = { ++ { 0, -1, 32 }, /* r0 */ ++ { 1, -1, 32 }, /* r1 */ ++ { 2, -1, 32 }, /* r2 */ ++ { 3, -1, 32 }, /* r3 */ ++ { 4, -1, 32 }, /* r4 */ ++ { 5, -1, 32 }, /* r5 */ ++ { 6, -1, 32 }, /* r6 */ ++ { 7, -1, 32 }, /* r7 */ ++ { 8, -1, 32 }, /* r8 */ ++ { 9, -1, 32 }, /* r9 */ ++ { 10, -1, 32 }, /* r10 */ ++ { 11, -1, 32 }, /* r11 (fp) */ ++ { 12, -1, 32 }, /* r12 (ip) */ ++ { 13, -1, 32 }, /* sp (r13) */ ++ { 14, -1, 32 }, /* lr (r14) */ ++ { 15, -1, 32 }, /* pc (r15) */ ++ { 16, -1, 32 }, /* xPSR */ ++}; ++ ++static struct rtos_register_stacking rtos_ecos_stacking = { ++ .stack_registers_size = 0, ++ .stack_growth_direction = -1, ++ .num_output_registers = 0, ++ .calculate_process_stack = NULL, /* stack_alignment */ ++ .register_offsets = NULL ++}; ++ ++/* To avoid the run-time cost of matching explicit symbol names we push the ++ * lookup offsets to this *manually* maintained enumeration which must match the ++ * ecos_symbol_list[] order below. */ + enum ecos_symbol_values { + ECOS_VAL_THREAD_LIST = 0, +- ECOS_VAL_CURRENT_THREAD_PTR = 1 ++ ECOS_VAL_CURRENT_THREAD_PTR, ++ ECOS_VAL_COMMON_THREAD_NEXT_OFF, ++ ECOS_VAL_COMMON_THREAD_NEXT_SIZE, ++ ECOS_VAL_COMMON_THREAD_STATE_OFF, ++ ECOS_VAL_COMMON_THREAD_STATE_SIZE, ++ ECOS_VAL_COMMON_THREAD_SLEEP_OFF, ++ ECOS_VAL_COMMON_THREAD_SLEEP_SIZE, ++ ECOS_VAL_COMMON_THREAD_WAKE_OFF, ++ ECOS_VAL_COMMON_THREAD_WAKE_SIZE, ++ ECOS_VAL_COMMON_THREAD_ID_OFF, ++ ECOS_VAL_COMMON_THREAD_ID_SIZE, ++ ECOS_VAL_COMMON_THREAD_NAME_OFF, ++ ECOS_VAL_COMMON_THREAD_NAME_SIZE, ++ ECOS_VAL_COMMON_THREAD_PRI_OFF, ++ ECOS_VAL_COMMON_THREAD_PRI_SIZE, ++ ECOS_VAL_COMMON_THREAD_STACK_OFF, ++ ECOS_VAL_COMMON_THREAD_STACK_SIZE, ++ ECOS_VAL_CORTEXM_THREAD_SAVED, ++ ECOS_VAL_CORTEXM_CTX_THREAD_SIZE, ++ ECOS_VAL_CORTEXM_CTX_TYPE_OFF, ++ ECOS_VAL_CORTEXM_CTX_TYPE_SIZE, ++ ECOS_VAL_CORTEXM_CTX_BASEPRI_OFF, ++ ECOS_VAL_CORTEXM_CTX_BASEPRI_SIZE, ++ ECOS_VAL_CORTEXM_CTX_SP_OFF, ++ ECOS_VAL_CORTEXM_CTX_SP_SIZE, ++ ECOS_VAL_CORTEXM_CTX_REG_OFF, ++ ECOS_VAL_CORTEXM_CTX_REG_SIZE, ++ ECOS_VAL_CORTEXM_CTX_PC_OFF, ++ ECOS_VAL_CORTEXM_CTX_PC_SIZE, ++ ECOS_VAL_CORTEXM_VAL_EXCEPTION, ++ ECOS_VAL_CORTEXM_VAL_THREAD, ++ ECOS_VAL_CORTEXM_VAL_INTERRUPT, ++ ECOS_VAL_CORTEXM_VAL_FPU, ++ ECOS_VAL_CORTEXM_CTX_FPSCR_OFF, ++ ECOS_VAL_CORTEXM_CTX_FPSCR_SIZE, ++ ECOS_VAL_CORTEXM_CTX_S_OFF, ++ ECOS_VAL_CORTEXM_CTX_S_SIZE, ++ ECOS_VAL_ARM_REGSIZE, ++ ECOS_VAL_ARM_CTX_R0_OFF, ++ ECOS_VAL_ARM_CTX_R1_OFF, ++ ECOS_VAL_ARM_CTX_R2_OFF, ++ ECOS_VAL_ARM_CTX_R3_OFF, ++ ECOS_VAL_ARM_CTX_R4_OFF, ++ ECOS_VAL_ARM_CTX_R5_OFF, ++ ECOS_VAL_ARM_CTX_R6_OFF, ++ ECOS_VAL_ARM_CTX_R7_OFF, ++ ECOS_VAL_ARM_CTX_R8_OFF, ++ ECOS_VAL_ARM_CTX_R9_OFF, ++ ECOS_VAL_ARM_CTX_R10_OFF, ++ ECOS_VAL_ARM_CTX_FP_OFF, ++ ECOS_VAL_ARM_CTX_IP_OFF, ++ ECOS_VAL_ARM_CTX_SP_OFF, ++ ECOS_VAL_ARM_CTX_LR_OFF, ++ ECOS_VAL_ARM_CTX_PC_OFF, ++ ECOS_VAL_ARM_CTX_CPSR_OFF, ++ ECOS_VAL_ARM_FPUSIZE, ++ ECOS_VAL_ARM_CTX_FPSCR_OFF, ++ ECOS_VAL_ARM_SCOUNT, ++ ECOS_VAL_ARM_CTX_SVEC_OFF, ++ ECOS_VAL_ARM_VFPCOUNT, ++ ECOS_VAL_ARM_CTX_VFPVEC_OFF + }; + +-static const char * const ecos_symbol_list[] = { +- "Cyg_Thread::thread_list", +- "Cyg_Scheduler_Base::current_thread", +- NULL ++struct symbols { ++ const char *name; ++ const char * const *target_names; /* non-NULL when for a specific architecture */ ++ bool optional; ++}; ++ ++#define ECOSSYM(_n, _o, _t) { .name = _n, .optional = (_o), .target_names = _t } ++ ++/* Some of offset/size helper symbols are common to all eCos ++ * targets. Unfortunately, for historical reasons, some information is in ++ * architecture specific namespaces leading to some duplication and a larger ++ * vector below. */ ++static const struct symbols ecos_symbol_list[] = { ++ ECOSSYM("Cyg_Thread::thread_list", false, NULL), ++ ECOSSYM("Cyg_Scheduler_Base::current_thread", false, NULL), ++ /* Following symbols *are* required for generic application-specific ++ * configuration support, but we mark as optional for backwards ++ * compatibility with the previous fixed Cortex-M3 only RTOS plugin ++ * implementation. */ ++ ECOSSYM("__ecospro_syminfo.off.cyg_thread.list_next", true, NULL), ++ ECOSSYM("__ecospro_syminfo.size.cyg_thread.list_next", true, NULL), ++ ECOSSYM("__ecospro_syminfo.off.cyg_thread.state", true, NULL), ++ ECOSSYM("__ecospro_syminfo.size.cyg_thread.state", true, NULL), ++ ECOSSYM("__ecospro_syminfo.off.cyg_thread.sleep_reason", true, NULL), ++ ECOSSYM("__ecospro_syminfo.size.cyg_thread.sleep_reason", true, NULL), ++ ECOSSYM("__ecospro_syminfo.off.cyg_thread.wake_reason", true, NULL), ++ ECOSSYM("__ecospro_syminfo.size.cyg_thread.wake_reason", true, NULL), ++ ECOSSYM("__ecospro_syminfo.off.cyg_thread.unique_id", true, NULL), ++ ECOSSYM("__ecospro_syminfo.size.cyg_thread.unique_id", true, NULL), ++ ECOSSYM("__ecospro_syminfo.off.cyg_thread.name", true, NULL), ++ ECOSSYM("__ecospro_syminfo.size.cyg_thread.name", true, NULL), ++ ECOSSYM("__ecospro_syminfo.off.cyg_thread.priority", true, NULL), ++ ECOSSYM("__ecospro_syminfo.size.cyg_thread.priority", true, NULL), ++ ECOSSYM("__ecospro_syminfo.off.cyg_thread.stack_ptr", true, NULL), ++ ECOSSYM("__ecospro_syminfo.size.cyg_thread.stack_ptr", true, NULL), ++ /* optional Cortex-M: */ ++ ECOSSYM("__ecospro_syminfo.cortexm.thread.saved", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.Thread", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.type", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.type", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.basepri", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.basepri", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.sp", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.sp", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.r", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.r", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.pc", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.pc", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.value.HAL_SAVEDREGISTERS.EXCEPTION", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.value.HAL_SAVEDREGISTERS.THREAD", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.value.HAL_SAVEDREGISTERS.INTERRUPT", true, target_cortex_m), ++ /* optional Cortex-M with H/W FPU configured: */ ++ ECOSSYM("__ecospro_syminfo.value.HAL_SAVEDREGISTERS.WITH_FPU", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.fpscr", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.fpscr", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.s", true, target_cortex_m), ++ ECOSSYM("__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.s", true, target_cortex_m), ++ /* optional ARM: */ ++ ECOSSYM("ARMREG_SIZE", true, target_arm), ++ ECOSSYM("armreg_r0", true, target_arm), ++ ECOSSYM("armreg_r1", true, target_arm), ++ ECOSSYM("armreg_r2", true, target_arm), ++ ECOSSYM("armreg_r3", true, target_arm), ++ ECOSSYM("armreg_r4", true, target_arm), ++ ECOSSYM("armreg_r5", true, target_arm), ++ ECOSSYM("armreg_r6", true, target_arm), ++ ECOSSYM("armreg_r7", true, target_arm), ++ ECOSSYM("armreg_r8", true, target_arm), ++ ECOSSYM("armreg_r9", true, target_arm), ++ ECOSSYM("armreg_r10", true, target_arm), ++ ECOSSYM("armreg_fp", true, target_arm), ++ ECOSSYM("armreg_ip", true, target_arm), ++ ECOSSYM("armreg_sp", true, target_arm), ++ ECOSSYM("armreg_lr", true, target_arm), ++ ECOSSYM("armreg_pc", true, target_arm), ++ ECOSSYM("armreg_cpsr", true, target_arm), ++ /* optional ARM FPU common: */ ++ ECOSSYM("ARMREG_FPUCONTEXT_SIZE", true, target_arm), ++ ECOSSYM("armreg_fpscr", true, target_arm), ++ /* optional ARM FPU single-precision: */ ++ ECOSSYM("ARMREG_S_COUNT", true, target_arm), ++ ECOSSYM("armreg_s_vec", true, target_arm), ++ /* optional ARM FPU double-precision: */ ++ ECOSSYM("ARMREG_VFP_COUNT", true, target_arm), ++ ECOSSYM("armreg_vfp_vec", true, target_arm), + }; + + const struct rtos_type ecos_rtos = { +@@ -84,34 +464,280 @@ const struct rtos_type ecos_rtos = { + + }; + ++static symbol_address_t ecos_value(struct rtos *rtos, unsigned int idx) ++{ ++ if (idx < ARRAY_SIZE(ecos_symbol_list)) ++ return rtos->symbols[idx].address; ++ ++ /* We do not terminate, just return 0 in this case. */ ++ LOG_ERROR("eCos: Invalid symbol index %u", idx); ++ return 0; ++} ++ ++#define XMLENTRY(_c, _s) { .xc = (_c), .rs = (_s), .rlen = (sizeof(_s) - 1) } ++ ++static const struct { ++ char xc; ++ const char *rs; ++ size_t rlen; ++} xmlchars[] = { ++ XMLENTRY('<', "<"), ++ XMLENTRY('&', "&"), ++ XMLENTRY('>', ">"), ++ XMLENTRY('\'', "'"), ++ XMLENTRY('"', """) ++}; ++ ++/** Escape any XML reserved characters in a string. */ ++static bool ecos_escape_string(const char *raw, char *out, size_t limit) ++{ ++ static const char *tokens = "<&>\'\""; ++ bool escaped = false; ++ ++ if (!out || !limit) ++ return false; ++ ++ (void)memset(out, '\0', limit); ++ ++ while (raw && *raw && limit) { ++ size_t lok = strcspn(raw, tokens); ++ if (lok) { ++ size_t tocopy; ++ tocopy = ((limit < lok) ? limit : lok); ++ (void)memcpy(out, raw, tocopy); ++ limit -= tocopy; ++ out += tocopy; ++ raw += lok; ++ continue; ++ } ++ ++ char *fidx = strchr(tokens, *raw); ++ if (!fidx) { ++ /* Should never happen assuming xmlchars ++ * vector and tokens string match. */ ++ LOG_ERROR("eCos: Unexpected XML char %c", *raw); ++ continue; ++ } ++ ++ uint32_t cidx = (fidx - tokens); ++ size_t tocopy = xmlchars[cidx].rlen; ++ if (limit < tocopy) ++ break; ++ ++ escaped = true; ++ (void)memcpy(out, xmlchars[cidx].rs, tocopy); ++ limit -= tocopy; ++ out += tocopy; ++ raw++; ++ } ++ ++ return escaped; ++} ++ ++static int ecos_check_app_info(struct rtos *rtos, struct ecos_params *param) ++{ ++ if (!rtos || !param) ++ return -1; ++ ++ if (param->flush_common) { ++ if (debug_level >= LOG_LVL_DEBUG) { ++ for (unsigned int idx = 0; idx < ARRAY_SIZE(ecos_symbol_list); idx++) { ++ LOG_DEBUG("eCos: %s 0x%016" PRIX64 " %s", ++ rtos->symbols[idx].optional ? "OPTIONAL" : " ", ++ rtos->symbols[idx].address, rtos->symbols[idx].symbol_name); ++ } ++ } ++ ++ /* If "__ecospro_syminfo.size.cyg_thread.list_next" is non-zero then we ++ * expect all of the generic thread structure symbols to have been ++ * provided. */ ++ symbol_address_t thread_next_size = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NEXT_SIZE); ++ if (thread_next_size != 0) { ++ param->pointer_width = thread_next_size; ++ param->uid_width = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_ID_SIZE); ++ param->state_width = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STATE_SIZE); ++ param->thread_stack_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STACK_OFF); ++ param->thread_name_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NAME_OFF); ++ param->thread_state_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STATE_OFF); ++ param->thread_next_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NEXT_OFF); ++ param->thread_uniqueid_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_ID_OFF); ++ } ++ ++ if (param->uid_width != sizeof(uint16_t)) { ++ /* Currently all eCos configurations use a 16-bit field to hold the ++ * unique thread ID. */ ++ LOG_WARNING("eCos: Unexpected unique_id width %" PRIu8, param->uid_width); ++ param->uid_width = (unsigned char)sizeof(uint16_t); ++ } ++ ++ param->stacking_info = NULL; ++ param->flush_common = false; ++ } ++ ++ return ERROR_OK; ++} ++ ++/* The Cortex-M eCosPro "thread" contexts have a "type" indicator, which tracks ++ * the context state of (THREAD | EXCEPTION | INTERRUPT) and whether FPU ++ * registers are saved. ++ * ++ * For thread-aware debugging from GDB we are only interested in THREAD states ++ * and so do not need to implement support for INTERRUPT or EXCEPTION thread ++ * contexts since this code does not expose those stack contexts via the ++ * constructed thread list support. */ ++static int ecos_stack_layout_cortexm(struct rtos *rtos, ++ struct ecos_params *param, int64_t stack_ptr, ++ const struct rtos_register_stacking **si) ++{ ++ int retval = ERROR_OK; ++ ++ /* CONSIDER: We could return ++ * ecos_value(rtos, ECOS_VAL_CORTEXM_THREAD_SAVED) as the actual PC ++ * address of a context switch, with the LR being set to the context PC ++ * field to give a true representation of where the thread switch ++ * occurs. However that would require extending the common ++ * rtos_generic_stack_read() code with suitable support for applying a ++ * supplied value, or just implementing our own version of that code that ++ * can inject data into what is passed onwards to GDB. */ ++ ++ /* UPDATE: When we can return VFP register state then we will NOT be ++ * basing the cached state on the single param->stacking_info value, ++ * since we will need a different stacking_info structure returned for ++ * each thread type when FPU support is enabled. The use of the single ++ * param->stacking_info is a holder whilst we are limited to the fixed ++ * ARMV7M_NUM_CORE_REGS set of descriptors. */ ++ ++ if (!param->stacking_info && ++ ecos_value(rtos, ECOS_VAL_CORTEXM_THREAD_SAVED) && ++ ecos_value(rtos, ECOS_VAL_CORTEXM_VAL_THREAD)) { ++ unsigned char numoutreg = ECOS_CORTEXM_BASE_NUMREGS; ++ ++ rtos_ecos_stacking.stack_registers_size = ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_THREAD_SIZE); ++ rtos_ecos_stacking.calculate_process_stack = rtos_generic_stack_align8; ++ rtos_ecos_stacking.register_offsets = rtos_ecos_regoff_cortexm; ++ ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R0].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x00); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R1].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x04); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R2].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x08); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R3].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x0C); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R4].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x10); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R5].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x14); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R6].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x18); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R7].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x1C); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R8].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x20); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R9].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x24); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R10].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x28); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R11].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x2C); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R12].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x30); ++ /* Rather than using the stacked ECOS_VAL_CORTEXM_CTX_SP_OFF ++ * value we force the reported sp to be after the stacked ++ * register context. */ ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R13].offset = -2; ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_R14].offset = -1; ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_PC].offset = ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_PC_OFF); ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_XPSR].offset = -1; ++ ++ param->stacking_info = &rtos_ecos_stacking; ++ ++ /* Common Cortex-M thread register offsets for the current ++ * symbol table: */ ++ if (retval == ERROR_OK && param->stacking_info) { ++ if (numoutreg > ECOS_REGLIST_BASEPRI) { ++ rtos_ecos_regoff_cortexm[ECOS_REGLIST_BASEPRI].offset = ++ ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_BASEPRI_OFF); ++ } ++ ++ rtos_ecos_stacking.num_output_registers = numoutreg; ++ } ++ } ++ ++ if (si) ++ *si = param->stacking_info; ++ ++ return retval; ++} ++ ++static int ecos_stack_layout_arm(struct rtos *rtos, struct ecos_params *param, ++ int64_t stack_ptr, const struct rtos_register_stacking **si) ++{ ++ int retval = ERROR_OK; ++ ++ if (!param->stacking_info && ecos_value(rtos, ECOS_VAL_ARM_REGSIZE)) { ++ /* When OpenOCD is extended to allow FPU registers to be returned from a ++ * stacked thread context we can check: ++ * if (0 != ecos_value(rtos, ECOS_VAL_ARM_FPUSIZE)) { FPU } ++ * for presence of FPU registers in the context. */ ++ ++ rtos_ecos_stacking.stack_registers_size = ecos_value(rtos, ECOS_VAL_ARM_REGSIZE); ++ rtos_ecos_stacking.num_output_registers = ARRAY_SIZE(rtos_ecos_regoff_arm); ++ rtos_ecos_stacking.register_offsets = rtos_ecos_regoff_arm; ++ ++ rtos_ecos_regoff_arm[0].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R0_OFF); ++ rtos_ecos_regoff_arm[1].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R1_OFF); ++ rtos_ecos_regoff_arm[2].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R2_OFF); ++ rtos_ecos_regoff_arm[3].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R3_OFF); ++ rtos_ecos_regoff_arm[4].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R4_OFF); ++ rtos_ecos_regoff_arm[5].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R5_OFF); ++ rtos_ecos_regoff_arm[6].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R6_OFF); ++ rtos_ecos_regoff_arm[7].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R7_OFF); ++ rtos_ecos_regoff_arm[8].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R8_OFF); ++ rtos_ecos_regoff_arm[9].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R9_OFF); ++ rtos_ecos_regoff_arm[10].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R10_OFF); ++ rtos_ecos_regoff_arm[11].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_FP_OFF); ++ rtos_ecos_regoff_arm[12].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_IP_OFF); ++ rtos_ecos_regoff_arm[13].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_SP_OFF); ++ rtos_ecos_regoff_arm[14].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_LR_OFF); ++ rtos_ecos_regoff_arm[15].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_PC_OFF); ++ rtos_ecos_regoff_arm[16].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_CPSR_OFF); ++ ++ param->stacking_info = &rtos_ecos_stacking; ++ } ++ ++ if (si) ++ *si = param->stacking_info; ++ ++ return retval; ++} ++ ++/* We see this function called on a new connection, it looks like before and ++ * after the "tar rem"/"tar extended-remote". It might be the only point we can ++ * decide to cache information (to check if the symbol table has changed). */ + static int ecos_update_threads(struct rtos *rtos) + { + int retval; + int tasks_found = 0; + int thread_list_size = 0; +- const struct ecos_params *param; ++ struct ecos_params *param; + + if (!rtos) + return -1; + ++ /* wipe out previous thread details if any */ ++ rtos_free_threadlist(rtos); ++ + if (!rtos->rtos_specific_params) + return -3; + +- param = (const struct ecos_params *) rtos->rtos_specific_params; ++ param = rtos->rtos_specific_params; + + if (!rtos->symbols) { ++ /* NOTE: We only see this when connecting from GDB the first ++ * time before the application image is loaded. So it is not a ++ * hook for detecting an application change. */ ++ param->flush_common = true; + LOG_ERROR("No symbols for eCos"); + return -4; + } + ++ retval = ecos_check_app_info(rtos, param); ++ if (retval != ERROR_OK) ++ return retval; ++ + if (rtos->symbols[ECOS_VAL_THREAD_LIST].address == 0) { + LOG_ERROR("Don't have the thread list head"); + return -2; + } + +- /* wipe out previous thread details if any */ +- rtos_free_threadlist(rtos); +- + /* determine the number of current threads */ + uint32_t thread_list_head = rtos->symbols[ECOS_VAL_THREAD_LIST].address; + uint32_t thread_index; +@@ -120,50 +746,82 @@ static int ecos_update_threads(struct rtos *rtos) + param->pointer_width, + (uint8_t *) &thread_index); + uint32_t first_thread = thread_index; +- do { +- thread_list_size++; +- retval = target_read_buffer(rtos->target, +- thread_index + param->thread_next_offset, +- param->pointer_width, +- (uint8_t *) &thread_index); +- if (retval != ERROR_OK) +- return retval; +- } while (thread_index != first_thread); ++ ++ /* Even if 0==first_thread indicates a system with no defined eCos ++ * threads, instead of early exiting here we fall through the code to ++ * allow the creation of a faked "Current Execution" descriptor as ++ * needed. */ ++ ++ if (first_thread) { ++ /* Since the OpenOCD RTOS support can attempt to obtain thread ++ * information on initial connection when the system *may* have ++ * undefined memory state it is possible for a simple thread count scan ++ * to produce invalid results. To avoid blocking indefinitely when ++ * encountering an invalid closed loop we limit the number of threads to ++ * the maximum possible, and if we pass that limit then something is ++ * wrong so treat the system as having no threads defined. */ ++ do { ++ thread_list_size++; ++ if (thread_list_size > ECOS_MAX_THREAD_COUNT) { ++ /* Treat as "no threads" case: */ ++ first_thread = 0; ++ thread_list_size = 0; ++ break; ++ } ++ retval = target_read_buffer(rtos->target, ++ thread_index + param->thread_next_offset, ++ param->pointer_width, ++ (uint8_t *)&thread_index); ++ if (retval != ERROR_OK) ++ return retval; ++ } while (thread_index != first_thread); ++ } + + /* read the current thread id */ ++ rtos->current_thread = 0; ++ + uint32_t current_thread_addr; + retval = target_read_buffer(rtos->target, + rtos->symbols[ECOS_VAL_CURRENT_THREAD_PTR].address, +- 4, ++ param->pointer_width, + (uint8_t *)¤t_thread_addr); +- if (retval != ERROR_OK) +- return retval; +- rtos->current_thread = 0; +- retval = target_read_buffer(rtos->target, +- current_thread_addr + param->thread_uniqueid_offset, +- 2, +- (uint8_t *)&rtos->current_thread); + if (retval != ERROR_OK) { +- LOG_ERROR("Could not read eCos current thread from target"); ++ LOG_ERROR("Reading active thread address"); + return retval; + } + +- if ((thread_list_size == 0) || (rtos->current_thread == 0)) { ++ if (current_thread_addr) { ++ uint16_t id = 0; ++ retval = target_read_buffer(rtos->target, ++ current_thread_addr + param->thread_uniqueid_offset, ++ param->uid_width, ++ (uint8_t *)&id); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read eCos current thread from target"); ++ return retval; ++ } ++ rtos->current_thread = (threadid_t)id; ++ } ++ ++ if (thread_list_size == 0 || rtos->current_thread == 0) { + /* Either : No RTOS threads - there is always at least the current execution though */ + /* OR : No current thread - all threads suspended - show the current execution + * of idling */ +- char tmp_str[] = "Current Execution"; ++ static const char tmp_str[] = "Current Execution"; + thread_list_size++; + tasks_found++; + rtos->thread_details = malloc( + sizeof(struct thread_detail) * thread_list_size); +- rtos->thread_details->threadid = 1; ++ /* 1 is a valid eCos thread id, so we return 0 for this faked ++ * "current" CPU state: */ ++ rtos->thread_details->threadid = 0; + rtos->thread_details->exists = true; + rtos->thread_details->extra_info_str = NULL; + rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str)); + strcpy(rtos->thread_details->thread_name_str, tmp_str); + +- if (thread_list_size == 0) { ++ /* Early exit if current CPU state our only "thread": */ ++ if (thread_list_size == 1) { + rtos->thread_count = 1; + return ERROR_OK; + } +@@ -176,18 +834,18 @@ static int ecos_update_threads(struct rtos *rtos) + /* loop over all threads */ + thread_index = first_thread; + do { +- + #define ECOS_THREAD_NAME_STR_SIZE (200) + char tmp_str[ECOS_THREAD_NAME_STR_SIZE]; +- unsigned int i = 0; + uint32_t name_ptr = 0; + uint32_t prev_thread_ptr; + +- /* Save the thread pointer */ +- uint16_t thread_id; ++ /* Save the thread ID. For eCos the thread has a unique ID distinct from ++ * the thread_index descriptor pointer. We present this scheduler ID ++ * instead of the descriptor memory address. */ ++ uint16_t thread_id = 0; + retval = target_read_buffer(rtos->target, + thread_index + param->thread_uniqueid_offset, +- 2, ++ param->uid_width, + (uint8_t *)&thread_id); + if (retval != ERROR_OK) { + LOG_ERROR("Could not read eCos thread id from target"); +@@ -195,7 +853,7 @@ static int ecos_update_threads(struct rtos *rtos) + } + rtos->thread_details[tasks_found].threadid = thread_id; + +- /* read the name pointer */ ++ /* Read the name pointer */ + retval = target_read_buffer(rtos->target, + thread_index + param->thread_name_offset, + param->pointer_width, +@@ -217,8 +875,26 @@ static int ecos_update_threads(struct rtos *rtos) + } + tmp_str[ECOS_THREAD_NAME_STR_SIZE-1] = '\x00'; + +- if (tmp_str[0] == '\x00') +- strcpy(tmp_str, "No Name"); ++ /* Since eCos can have arbitrary C string names we can sometimes ++ * get an internal warning from GDB about "not well-formed ++ * (invalid token)" since the XML post-processing done by GDB on ++ * the OpenOCD returned response containing the thread strings ++ * is not escaped. For example the eCos kernel testsuite ++ * application tm_basic uses the thread name "<>" which ++ * will trigger this failure unless escaped. */ ++ if (tmp_str[0] == '\x00') { ++ snprintf(tmp_str, ECOS_THREAD_NAME_STR_SIZE, "NoName:[0x%08" PRIX32 "]", thread_index); ++ } else { ++ /* The following is a workaround to avoid any issues ++ * from arbitrary eCos thread names causing GDB/OpenOCD ++ * issues. We limit the escaped thread name passed to ++ * GDB to the same length as the un-escaped just to ++ * avoid overly long strings. */ ++ char esc_str[ECOS_THREAD_NAME_STR_SIZE]; ++ bool escaped = ecos_escape_string(tmp_str, esc_str, sizeof(esc_str)); ++ if (escaped) ++ strcpy(tmp_str, esc_str); ++ } + + rtos->thread_details[tasks_found].thread_name_str = + malloc(strlen(tmp_str)+1); +@@ -228,28 +904,109 @@ static int ecos_update_threads(struct rtos *rtos) + int64_t thread_status = 0; + retval = target_read_buffer(rtos->target, + thread_index + param->thread_state_offset, +- 4, ++ param->state_width, + (uint8_t *)&thread_status); + if (retval != ERROR_OK) { + LOG_ERROR("Error reading thread state from eCos target"); + return retval; + } + +- for (i = 0; (i < ECOS_NUM_STATES) && (ecos_thread_states[i].value != thread_status); i++) { +- /* +- * empty +- */ +- } ++ /* The thread_status is a BITMASK */ ++ char state_desc[21]; /* Enough for "suspended+countsleep\0" maximum */ + +- const char *state_desc; +- if (i < ECOS_NUM_STATES) +- state_desc = ecos_thread_states[i].desc; ++ if (thread_status & SUSPENDED) ++ strcpy(state_desc, "suspended+"); + else +- state_desc = "Unknown state"; ++ state_desc[0] = '\0'; ++ ++ switch (thread_status & ~SUSPENDED) { ++ case RUNNING: ++ if (thread_index == current_thread_addr) ++ strcat(state_desc, "running"); ++ else if (thread_status & SUSPENDED) ++ state_desc[9] = '\0'; /* Drop '+' from "suspended+" */ ++ else ++ strcat(state_desc, "ready"); ++ break; ++ case SLEEPING: ++ strcat(state_desc, "sleeping"); ++ break; ++ case SLEEPSET: ++ case COUNTSLEEP: ++ strcat(state_desc, "counted sleep"); ++ break; ++ case CREATING: ++ strcpy(state_desc, "creating"); ++ break; ++ case EXITED: ++ strcpy(state_desc, "exited"); ++ break; ++ default: ++ strcpy(state_desc, "unknown state"); ++ break; ++ } ++ ++ /* For the moment we do not bother decoding the wake reason for the ++ * active "running" thread, but it is useful providing the sleep reason ++ * for stacked threads. */ ++ int64_t sleep_reason = 0; /* sleep reason */ ++ ++ if (thread_index != current_thread_addr && ++ ecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_SIZE)) { ++ retval = target_read_buffer(rtos->target, ++ (thread_index + ecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_OFF)), ++ ecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_SIZE), ++ (uint8_t *)&sleep_reason); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Error reading thread sleep reason from eCos target"); ++ return retval; ++ } ++ if (sleep_reason < 0 || ++ sleep_reason > (int64_t)ARRAY_SIZE(ecos_thread_reasons)) { ++ sleep_reason = 0; ++ } ++ } ++ ++ /* We do not display anything for the Cyg_Thread::NONE reason */ ++ size_t tr_extra = 0; ++ const char *reason_desc = NULL; ++ if (sleep_reason) ++ reason_desc = ecos_thread_reasons[sleep_reason].desc; ++ if (reason_desc) ++ tr_extra = 2 + strlen(reason_desc) + 1; + +- rtos->thread_details[tasks_found].extra_info_str = malloc(strlen( +- state_desc)+8); +- sprintf(rtos->thread_details[tasks_found].extra_info_str, "State: %s", state_desc); ++ /* Display thread priority if available: */ ++ int64_t priority = 0; ++ size_t pri_extra = 0; ++ if (ecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_SIZE)) { ++ retval = target_read_buffer(rtos->target, ++ (thread_index + ecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_OFF)), ++ ecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_SIZE), ++ (uint8_t *)&priority); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Error reading thread priority from eCos target"); ++ return retval; ++ } ++ pri_extra = (12 + 20); /* worst-case ", Priority: " */ ++ } ++ ++ size_t eilen = (8 + strlen(state_desc) + tr_extra + pri_extra); ++ char *eistr = malloc(eilen); ++ /* We do not need to treat a malloc failure as a fatal error here since ++ * the code below will just not report extra thread information if NULL, ++ * thus allowing all of the threads to be enumerated even with reduced ++ * information when the host is low on memory. However... */ ++ if (!eistr) { ++ LOG_ERROR("OOM allocating extra information buffer"); ++ return ERROR_FAIL; ++ } ++ ++ int soff = snprintf(eistr, eilen, "State: %s", state_desc); ++ if (tr_extra && reason_desc) ++ soff += snprintf(&eistr[soff], (eilen - soff), " (%s)", reason_desc); ++ if (pri_extra) ++ (void)snprintf(&eistr[soff], (eilen - soff), ", Priority: %" PRId64 "", priority); ++ rtos->thread_details[tasks_found].extra_info_str = eistr; + + rtos->thread_details[tasks_found].exists = true; + +@@ -269,14 +1026,14 @@ static int ecos_update_threads(struct rtos *rtos) + } while (thread_index != first_thread); + + rtos->thread_count = tasks_found; +- return 0; ++ return ERROR_OK; + } + + static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + struct rtos_reg **reg_list, int *num_regs) + { + int retval; +- const struct ecos_params *param; ++ struct ecos_params *param; + + if (!rtos) + return -1; +@@ -287,7 +1044,22 @@ static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + if (!rtos->rtos_specific_params) + return -3; + +- param = (const struct ecos_params *) rtos->rtos_specific_params; ++ param = rtos->rtos_specific_params; ++ ++ retval = ecos_check_app_info(rtos, param); ++ if (retval != ERROR_OK) ++ return retval; ++ ++ /* We can get memory access errors reported by this function on ++ * re-connecting to a board with stale thread information in memory. The ++ * initial ecos_update_threads() is called twice and may read ++ * stale/invalid information depending on the memory state. This happens ++ * as part of the "target remote" connection so cannot be avoided by GDB ++ * scripting. It is not critical and allowing the application to run and ++ * initialise its BSS etc. will allow correct thread and register ++ * information to be obtained. This really only affects debug sessions ++ * where "info thr" is used before the initial run-time initialisation ++ * has occurred. */ + + /* Find the thread with that thread id */ + uint16_t id = 0; +@@ -299,10 +1071,10 @@ static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + while (!done) { + retval = target_read_buffer(rtos->target, + thread_index + param->thread_uniqueid_offset, +- 2, ++ param->uid_width, + (uint8_t *)&id); + if (retval != ERROR_OK) { +- LOG_ERROR("Error reading unique id from eCos thread"); ++ LOG_ERROR("Error reading unique id from eCos thread 0x%08" PRIX32 "", thread_index); + return retval; + } + +@@ -328,8 +1100,24 @@ static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + return retval; + } + ++ if (!stack_ptr) { ++ LOG_ERROR("NULL stack pointer in thread %" PRIu64, thread_id); ++ return -5; ++ } ++ ++ const struct rtos_register_stacking *stacking_info = NULL; ++ if (param->target_stack_layout) { ++ retval = param->target_stack_layout(rtos, param, stack_ptr, &stacking_info); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Error reading stack layout for eCos thread"); ++ return retval; ++ } ++ } ++ if (!stacking_info) ++ stacking_info = &rtos_ecos_cortex_m3_stacking; ++ + return rtos_generic_stack_read(rtos->target, +- param->stacking_info, ++ stacking_info, + stack_ptr, + reg_list, + num_regs); +@@ -338,18 +1126,31 @@ static int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + return -1; + } + ++/* NOTE: This is only called once when the first GDB connection is made to ++ * OpenOCD and not on subsequent connections (when the application symbol table ++ * may have changed, affecting the offsets of critical fields and the stacked ++ * context shape). */ + static int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]) + { + unsigned int i; + *symbol_list = calloc( + ARRAY_SIZE(ecos_symbol_list), sizeof(struct symbol_table_elem)); + +- for (i = 0; i < ARRAY_SIZE(ecos_symbol_list); i++) +- (*symbol_list)[i].symbol_name = ecos_symbol_list[i]; ++ /* If the target reference was passed into this function we could limit ++ * the symbols we need to lookup to the target->type->name based ++ * range. For the moment we need to provide a single vector with all of ++ * the symbols across all of the supported architectures. */ ++ for (i = 0; i < ARRAY_SIZE(ecos_symbol_list); i++) { ++ (*symbol_list)[i].symbol_name = ecos_symbol_list[i].name; ++ (*symbol_list)[i].optional = ecos_symbol_list[i].optional; ++ } + + return 0; + } + ++/* NOTE: Only called by rtos.c:rtos_qsymbol() when auto-detecting the RTOS. If ++ * the target configuration uses the explicit "-rtos" config option then this ++ * detection routine is NOT called. */ + static bool ecos_detect_rtos(struct target *target) + { + if ((target->rtos->symbols) && +@@ -360,15 +1161,67 @@ static bool ecos_detect_rtos(struct target *target) + return false; + } + ++extern int rtos_thread_packet(struct connection *connection, ++ const char *packet, int packet_size); ++ ++/* Since we should never have 0 as a valid eCos thread ID we use $Hg0 as the ++ * indicator of a new session as regards flushing any cached state. */ ++static int ecos_packet_hook(struct connection *connection, ++ const char *packet, int packet_size) ++{ ++ int64_t current_threadid; ++ ++ if (packet[0] == 'H' && packet[1] == 'g') { ++ int numscan = sscanf(packet, "Hg%16" SCNx64, ¤t_threadid); ++ if (numscan == 1 && current_threadid == 0) { ++ struct target *target = get_target_from_connection(connection); ++ if (target && target->rtos && target->rtos->rtos_specific_params) { ++ struct ecos_params *param; ++ param = target->rtos->rtos_specific_params; ++ param->flush_common = true; ++ } ++ } ++ } ++ ++ return rtos_thread_packet(connection, packet, packet_size); ++} ++ ++/* Called at start of day when eCos detected or specified in config file. */ + static int ecos_create(struct target *target) + { +- for (unsigned int i = 0; i < ARRAY_SIZE(ecos_params_list); i++) +- if (strcmp(ecos_params_list[i].target_name, target->type->name) == 0) { +- target->rtos->rtos_specific_params = (void *)&ecos_params_list[i]; +- target->rtos->current_thread = 0; +- target->rtos->thread_details = NULL; +- return 0; ++ for (unsigned int i = 0; i < ARRAY_SIZE(ecos_params_list); i++) { ++ const char * const *tnames = ecos_params_list[i].target_names; ++ while (*tnames) { ++ if (strcmp(*tnames, target->type->name) == 0) { ++ /* LOG_DEBUG("eCos: matched target \"%s\"", target->type->name); */ ++ target->rtos->rtos_specific_params = (void *)&ecos_params_list[i]; ++ ecos_params_list[i].flush_common = true; ++ ecos_params_list[i].stacking_info = NULL; ++ target->rtos->current_thread = 0; ++ target->rtos->thread_details = NULL; ++ ++ /* We use the $Hg0 packet as a new GDB connection "start-of-day" hook to ++ * force a re-cache of information. It is possible for a single OpenOCD ++ * session to be connected to a target with multiple GDB debug sessions ++ * started/stopped. With eCos it is possible for those GDB sessions to ++ * present applications with different offsets within a thread ++ * descriptor for fields used by this module, and for the stacked ++ * context within the connected target architecture to differ between ++ * applications and even between threads in a single application. So we ++ * need to ensure any information we cache is flushed on an application ++ * change, and GDB referencing an invalid eCos thread ID (0) is a good ++ * enough point, since we can accept the re-cache hit if that packet ++ * appears during an established session, whilst benefiting from not ++ * re-loading information on every update_threads or get_thread_reg_list ++ * call. */ ++ target->rtos->gdb_thread_packet = ecos_packet_hook; ++ /* We do not currently use the target->rtos->gdb_target_for_threadid ++ * hook. */ ++ return 0; ++ } ++ tnames++; + } ++ } + + LOG_ERROR("Could not find target in eCos compatibility list"); + return -1; +diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c +index 0f54e86f7..86e176507 100644 +--- a/src/rtos/rtos_ecos_stackings.c ++++ b/src/rtos/rtos_ecos_stackings.c +@@ -8,6 +8,13 @@ + #include "rtos_standard_stackings.h" + #include "target/armv7m.h" + ++/* For Cortex-M eCos applications the actual thread context register layout can ++ * be different between active threads of an application depending on whether ++ * the FPU is in use, configured for lazy FPU context saving, etc. */ ++ ++/* Default fixed thread register context description used for older eCos ++ * application builds without the necessary symbolic information describing the ++ * actual configuration-dependent offsets. */ + static const struct stack_register_offset rtos_ecos_cortex_m3_stack_offsets[ARMV7M_NUM_CORE_REGS] = { + { ARMV7M_R0, 0x0c, 32 }, /* r0 */ + { ARMV7M_R1, 0x10, 32 }, /* r1 */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0009-armv8-Add-support-of-pointer-authentication.patch b/meta-oe/recipes-devtools/openocd/openocd/0009-armv8-Add-support-of-pointer-authentication.patch new file mode 100644 index 000000000..c9081a3f9 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0009-armv8-Add-support-of-pointer-authentication.patch @@ -0,0 +1,460 @@ +From d0436b0cdabb2106701222628d78932c973a1e62 Mon Sep 17 00:00:00 2001 +From: Koudai Iwahori +Date: Tue, 4 Oct 2022 04:21:35 -0700 +Subject: [PATCH] armv8: Add support of pointer authentication + +When pointer authentication is enabled, some upper bits of the link +register (LR[63:VA_SIZE]) are used to store a signature. Therefore, GDB +need to remove the signature to get backtraces. +GDB has support of pointer authentication. When pointer authenticaion is +enabled, GDB requests 8-bytes mask to the target to remove the +signature. mask[63:VA_SIZE] should be all set and mask[VA_SIZE-1:0] +should be all cleared. GDB removes the signature by addr&~mask or +addr|mask. +I added a feature to provide the mask for pointer authentication. + +Signed-off-by: Koudai Iwahori +Change-Id: I56fbbf9cc23619b6536ecd326f350c8bf137f322 +Reviewed-on: https://review.openocd.org/c/openocd/+/7248 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + doc/openocd.texi | 10 ++ + src/target/armv8.c | 335 +++++++++++++++++++++++++-------------------- + src/target/armv8.h | 7 + + 3 files changed, 206 insertions(+), 146 deletions(-) + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index c7fee3e71..aa1707b7d 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -10297,6 +10297,16 @@ the target, the exception catch must be disabled again with @command{$target_nam + Issuing the command without options prints the current configuration. + @end deffn + ++@deffn {Command} {$target_name pauth} [@option{off}|@option{on}] ++Enable or disable pointer authentication features. ++When pointer authentication is used on ARM cores, GDB asks GDB servers for an 8-bytes mask to remove signature bits added by pointer authentication. ++If this feature is enabled, OpenOCD provides GDB with an 8-bytes mask. ++Pointer authentication feature is broken until gdb 12.1, going to be fixed. ++Consider using a newer version of gdb if you want to enable pauth feature. ++The default configuration is @option{off}. ++@end deffn ++ ++ + @section EnSilica eSi-RISC Architecture + + eSi-RISC is a highly configurable microprocessor architecture for embedded systems +diff --git a/src/target/armv8.c b/src/target/armv8.c +index de0bddb3e..ff71a8e63 100644 +--- a/src/target/armv8.c ++++ b/src/target/armv8.c +@@ -114,6 +114,166 @@ const char *armv8_mode_name(unsigned psr_mode) + return "UNRECOGNIZED"; + } + ++static uint8_t armv8_pa_size(uint32_t ps) ++{ ++ uint8_t ret = 0; ++ switch (ps) { ++ case 0: ++ ret = 32; ++ break; ++ case 1: ++ ret = 36; ++ break; ++ case 2: ++ ret = 40; ++ break; ++ case 3: ++ ret = 42; ++ break; ++ case 4: ++ ret = 44; ++ break; ++ case 5: ++ ret = 48; ++ break; ++ default: ++ LOG_INFO("Unknown physical address size"); ++ break; ++ } ++ return ret; ++} ++ ++static __attribute__((unused)) int armv8_read_ttbcr32(struct target *target) ++{ ++ struct armv8_common *armv8 = target_to_armv8(target); ++ struct arm_dpm *dpm = armv8->arm.dpm; ++ uint32_t ttbcr, ttbcr_n; ++ int retval = dpm->prepare(dpm); ++ if (retval != ERROR_OK) ++ goto done; ++ /* MRC p15,0,,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/ ++ retval = dpm->instr_read_data_r0(dpm, ++ ARMV4_5_MRC(15, 0, 0, 2, 0, 2), ++ &ttbcr); ++ if (retval != ERROR_OK) ++ goto done; ++ ++ LOG_DEBUG("ttbcr %" PRIx32, ttbcr); ++ ++ ttbcr_n = ttbcr & 0x7; ++ armv8->armv8_mmu.ttbcr = ttbcr; ++ ++ /* ++ * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition), ++ * document # ARM DDI 0406C ++ */ ++ armv8->armv8_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n; ++ armv8->armv8_mmu.ttbr_range[1] = 0xffffffff; ++ armv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n); ++ armv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14; ++ ++ LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32, ++ (ttbcr_n != 0) ? "used" : "not used", ++ armv8->armv8_mmu.ttbr_mask[0], ++ armv8->armv8_mmu.ttbr_mask[1]); ++ ++done: ++ dpm->finish(dpm); ++ return retval; ++} ++ ++static int armv8_read_ttbcr(struct target *target) ++{ ++ struct armv8_common *armv8 = target_to_armv8(target); ++ struct arm_dpm *dpm = armv8->arm.dpm; ++ struct arm *arm = &armv8->arm; ++ uint32_t ttbcr; ++ uint64_t ttbcr_64; ++ ++ int retval = dpm->prepare(dpm); ++ if (retval != ERROR_OK) ++ goto done; ++ ++ /* clear ttrr1_used and ttbr0_mask */ ++ memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used)); ++ memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask)); ++ ++ switch (armv8_curel_from_core_mode(arm->core_mode)) { ++ case SYSTEM_CUREL_EL3: ++ retval = dpm->instr_read_data_r0(dpm, ++ ARMV8_MRS(SYSTEM_TCR_EL3, 0), ++ &ttbcr); ++ retval += dpm->instr_read_data_r0_64(dpm, ++ ARMV8_MRS(SYSTEM_TTBR0_EL3, 0), ++ &armv8->ttbr_base); ++ if (retval != ERROR_OK) ++ goto done; ++ armv8->va_size = 64 - (ttbcr & 0x3F); ++ armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7); ++ armv8->page_size = (ttbcr >> 14) & 3; ++ break; ++ case SYSTEM_CUREL_EL2: ++ retval = dpm->instr_read_data_r0(dpm, ++ ARMV8_MRS(SYSTEM_TCR_EL2, 0), ++ &ttbcr); ++ retval += dpm->instr_read_data_r0_64(dpm, ++ ARMV8_MRS(SYSTEM_TTBR0_EL2, 0), ++ &armv8->ttbr_base); ++ if (retval != ERROR_OK) ++ goto done; ++ armv8->va_size = 64 - (ttbcr & 0x3F); ++ armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7); ++ armv8->page_size = (ttbcr >> 14) & 3; ++ break; ++ case SYSTEM_CUREL_EL0: ++ armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H); ++ /* fall through */ ++ case SYSTEM_CUREL_EL1: ++ retval = dpm->instr_read_data_r0_64(dpm, ++ ARMV8_MRS(SYSTEM_TCR_EL1, 0), ++ &ttbcr_64); ++ armv8->va_size = 64 - (ttbcr_64 & 0x3F); ++ armv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7); ++ armv8->page_size = (ttbcr_64 >> 14) & 3; ++ armv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0; ++ armv8->armv8_mmu.ttbr0_mask = 0x0000FFFFFFFFFFFF; ++ retval += dpm->instr_read_data_r0_64(dpm, ++ ARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0), ++ &armv8->ttbr_base); ++ if (retval != ERROR_OK) ++ goto done; ++ break; ++ default: ++ LOG_ERROR("unknown core state"); ++ retval = ERROR_FAIL; ++ break; ++ } ++ if (retval != ERROR_OK) ++ goto done; ++ ++ if (armv8->armv8_mmu.ttbr1_used == 1) ++ LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask)); ++ ++done: ++ armv8_dpm_modeswitch(dpm, ARM_MODE_ANY); ++ dpm->finish(dpm); ++ return retval; ++} ++ ++static int armv8_get_pauth_mask(struct armv8_common *armv8, uint64_t *mask) ++{ ++ struct arm *arm = &armv8->arm; ++ int retval = ERROR_OK; ++ if (armv8->va_size == 0) ++ retval = armv8_read_ttbcr(arm->target); ++ if (retval != ERROR_OK) ++ return retval; ++ ++ *mask = ~(((uint64_t)1 << armv8->va_size) - 1); ++ ++ return retval; ++} ++ + static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regval) + { + struct arm_dpm *dpm = &armv8->dpm; +@@ -191,6 +351,10 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv + ARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value); + value_64 = value; + break; ++ case ARMV8_PAUTH_CMASK: ++ case ARMV8_PAUTH_DMASK: ++ retval = armv8_get_pauth_mask(armv8, &value_64); ++ break; + default: + retval = ERROR_FAIL; + break; +@@ -772,152 +936,6 @@ static __attribute__((unused)) void armv8_show_fault_registers(struct target *ta + armv8_show_fault_registers32(armv8); + } + +-static uint8_t armv8_pa_size(uint32_t ps) +-{ +- uint8_t ret = 0; +- switch (ps) { +- case 0: +- ret = 32; +- break; +- case 1: +- ret = 36; +- break; +- case 2: +- ret = 40; +- break; +- case 3: +- ret = 42; +- break; +- case 4: +- ret = 44; +- break; +- case 5: +- ret = 48; +- break; +- default: +- LOG_INFO("Unknown physical address size"); +- break; +- } +- return ret; +-} +- +-static __attribute__((unused)) int armv8_read_ttbcr32(struct target *target) +-{ +- struct armv8_common *armv8 = target_to_armv8(target); +- struct arm_dpm *dpm = armv8->arm.dpm; +- uint32_t ttbcr, ttbcr_n; +- int retval = dpm->prepare(dpm); +- if (retval != ERROR_OK) +- goto done; +- /* MRC p15,0,,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/ +- retval = dpm->instr_read_data_r0(dpm, +- ARMV4_5_MRC(15, 0, 0, 2, 0, 2), +- &ttbcr); +- if (retval != ERROR_OK) +- goto done; +- +- LOG_DEBUG("ttbcr %" PRIx32, ttbcr); +- +- ttbcr_n = ttbcr & 0x7; +- armv8->armv8_mmu.ttbcr = ttbcr; +- +- /* +- * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition), +- * document # ARM DDI 0406C +- */ +- armv8->armv8_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n; +- armv8->armv8_mmu.ttbr_range[1] = 0xffffffff; +- armv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n); +- armv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14; +- +- LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32, +- (ttbcr_n != 0) ? "used" : "not used", +- armv8->armv8_mmu.ttbr_mask[0], +- armv8->armv8_mmu.ttbr_mask[1]); +- +-done: +- dpm->finish(dpm); +- return retval; +-} +- +-static __attribute__((unused)) int armv8_read_ttbcr(struct target *target) +-{ +- struct armv8_common *armv8 = target_to_armv8(target); +- struct arm_dpm *dpm = armv8->arm.dpm; +- struct arm *arm = &armv8->arm; +- uint32_t ttbcr; +- uint64_t ttbcr_64; +- +- int retval = dpm->prepare(dpm); +- if (retval != ERROR_OK) +- goto done; +- +- /* clear ttrr1_used and ttbr0_mask */ +- memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used)); +- memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask)); +- +- switch (armv8_curel_from_core_mode(arm->core_mode)) { +- case SYSTEM_CUREL_EL3: +- retval = dpm->instr_read_data_r0(dpm, +- ARMV8_MRS(SYSTEM_TCR_EL3, 0), +- &ttbcr); +- retval += dpm->instr_read_data_r0_64(dpm, +- ARMV8_MRS(SYSTEM_TTBR0_EL3, 0), +- &armv8->ttbr_base); +- if (retval != ERROR_OK) +- goto done; +- armv8->va_size = 64 - (ttbcr & 0x3F); +- armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7); +- armv8->page_size = (ttbcr >> 14) & 3; +- break; +- case SYSTEM_CUREL_EL2: +- retval = dpm->instr_read_data_r0(dpm, +- ARMV8_MRS(SYSTEM_TCR_EL2, 0), +- &ttbcr); +- retval += dpm->instr_read_data_r0_64(dpm, +- ARMV8_MRS(SYSTEM_TTBR0_EL2, 0), +- &armv8->ttbr_base); +- if (retval != ERROR_OK) +- goto done; +- armv8->va_size = 64 - (ttbcr & 0x3F); +- armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7); +- armv8->page_size = (ttbcr >> 14) & 3; +- break; +- case SYSTEM_CUREL_EL0: +- armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H); +- /* fall through */ +- case SYSTEM_CUREL_EL1: +- retval = dpm->instr_read_data_r0_64(dpm, +- ARMV8_MRS(SYSTEM_TCR_EL1, 0), +- &ttbcr_64); +- armv8->va_size = 64 - (ttbcr_64 & 0x3F); +- armv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7); +- armv8->page_size = (ttbcr_64 >> 14) & 3; +- armv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0; +- armv8->armv8_mmu.ttbr0_mask = 0x0000FFFFFFFFFFFF; +- retval += dpm->instr_read_data_r0_64(dpm, +- ARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0), +- &armv8->ttbr_base); +- if (retval != ERROR_OK) +- goto done; +- break; +- default: +- LOG_ERROR("unknown core state"); +- retval = ERROR_FAIL; +- break; +- } +- if (retval != ERROR_OK) +- goto done; +- +- if (armv8->armv8_mmu.ttbr1_used == 1) +- LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask)); +- +-done: +- armv8_dpm_modeswitch(dpm, ARM_MODE_ANY); +- dpm->finish(dpm); +- return retval; +-} +- + /* method adapted to cortex A : reused arm v4 v5 method*/ + int armv8_mmu_translate_va(struct target *target, target_addr_t va, target_addr_t *val) + { +@@ -1083,6 +1101,15 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command) + return ERROR_OK; + } + ++COMMAND_HANDLER(armv8_pauth_command) ++{ ++ struct target *target = get_current_target(CMD_CTX); ++ struct armv8_common *armv8 = target_to_armv8(target); ++ return CALL_COMMAND_HANDLER(handle_command_parse_bool, ++ &armv8->enable_pauth, ++ "pauth feature"); ++} ++ + int armv8_handle_cache_info_command(struct command_invocation *cmd, + struct armv8_cache_common *armv8_cache) + { +@@ -1421,6 +1448,8 @@ static const struct { + NULL}, + { ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", + NULL}, ++ { ARMV8_PAUTH_DMASK, "pauth_dmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL}, ++ { ARMV8_PAUTH_CMASK, "pauth_cmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL}, + }; + + static const struct { +@@ -1650,6 +1679,9 @@ struct reg_cache *armv8_build_reg_cache(struct target *target) + *reg_list[i].reg_data_type = *armv8_regs[i].data_type; + } else + LOG_ERROR("unable to allocate reg type list"); ++ ++ if (i == ARMV8_PAUTH_CMASK || i == ARMV8_PAUTH_DMASK) ++ reg_list[i].hidden = !armv8->enable_pauth; + } + + arm->cpsr = reg_list + ARMV8_XPSR; +@@ -1745,6 +1777,17 @@ const struct command_registration armv8_command_handlers[] = { + .help = "configure exception catch", + .usage = "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]", + }, ++ { ++ .name = "pauth", ++ .handler = armv8_pauth_command, ++ .mode = COMMAND_CONFIG, ++ .help = "enable or disable providing GDB with an 8-bytes mask to " ++ "remove signature bits added by pointer authentication." ++ "Pointer authentication feature is broken until gdb 12.1, going to be fixed. " ++ "Consider using a newer version of gdb if you want enable " ++ "pauth feature.", ++ .usage = "[on|off]", ++ }, + COMMAND_REGISTRATION_DONE + }; + +diff --git a/src/target/armv8.h b/src/target/armv8.h +index 2ed3a65ac..54aa08634 100644 +--- a/src/target/armv8.h ++++ b/src/target/armv8.h +@@ -98,6 +98,10 @@ enum { + ARMV8_ESR_EL3 = 75, + ARMV8_SPSR_EL3 = 76, + ++ /* Pseudo registers defined by GDB to remove the pauth signature. */ ++ ARMV8_PAUTH_DMASK = 77, ++ ARMV8_PAUTH_CMASK = 78, ++ + ARMV8_LAST_REG, + }; + +@@ -205,6 +209,9 @@ struct armv8_common { + + struct arm_cti *cti; + ++ /* True if OpenOCD provides pointer auth related info to GDB */ ++ bool enable_pauth; ++ + /* last run-control command issued to this target (resume, halt, step) */ + enum run_control_op last_run_control_op; + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0010-target-armv7m-check-error-in-armv7m_restore_context.patch b/meta-oe/recipes-devtools/openocd/openocd/0010-target-armv7m-check-error-in-armv7m_restore_context.patch new file mode 100644 index 000000000..b694f5565 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0010-target-armv7m-check-error-in-armv7m_restore_context.patch @@ -0,0 +1,34 @@ +From 083100fca3c5fd019517e38028d26a6c8e33a364 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sat, 1 Oct 2022 17:00:51 +0200 +Subject: [PATCH] target/armv7m: check error in armv7m_restore_context() + +Return error if arm.write_core_reg() fails. + +Change-Id: Ide8f5aa5958532b202dc9f5e13d3250a706d832d +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7238 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/target/armv7m.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/target/armv7m.c b/src/target/armv7m.c +index 93df5877e..1b85315de 100644 +--- a/src/target/armv7m.c ++++ b/src/target/armv7m.c +@@ -182,8 +182,11 @@ int armv7m_restore_context(struct target *target) + for (i = cache->num_regs - 1; i >= 0; i--) { + struct reg *r = &cache->reg_list[i]; + +- if (r->exist && r->dirty) +- armv7m->arm.write_core_reg(target, r, i, ARM_MODE_ANY, r->value); ++ if (r->exist && r->dirty) { ++ int retval = armv7m->arm.write_core_reg(target, r, i, ARM_MODE_ANY, r->value); ++ if (retval != ERROR_OK) ++ return retval; ++ } + } + + return ERROR_OK; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0011-target-cortex_m-add-SMP-support-for-Cortex-M.patch b/meta-oe/recipes-devtools/openocd/openocd/0011-target-cortex_m-add-SMP-support-for-Cortex-M.patch new file mode 100644 index 000000000..bffd6269c --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0011-target-cortex_m-add-SMP-support-for-Cortex-M.patch @@ -0,0 +1,400 @@ +From 59763653c631625f195bf652f226f8537fe66832 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sat, 1 Oct 2022 17:10:31 +0200 +Subject: [PATCH] target/cortex_m: add SMP support for Cortex-M + +Cortex-M support for SMP multicore targets. + +This SMP implementation unlike older ones does not act +on the first halted target found. It polls targets +until a SMP group is finished and stores eventual +'halted' events instead of emitting them. As soon as polling +of a group is done, poll proceeds with SMP related tasks. +This approach improves detection of a reason why debug +stopped - a correct reason is detected for all targets, +not only for the first found. +Drawback: SMP target group should be defined in the same +order as the targets were defined. + +Obsolete gdb 'J' packet/smp_gdb command core switching is not implemented, +use with rtos hwthread. + +Only one core is resumed if debug_execution is requested. + +Some ideas taken from Graham Sanderson's [4936] +and src/target/aarch64.c + +Added error checking of armv7m_restore_context(). + +Change-Id: I60f5b79e74b624dc2b5835ff10e38ac2ccb23792 +Link: [4936]: target/cortex_m: Add smp support for Cortex M | https://review.openocd.org/c/openocd/+/4936 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7239 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/target/cortex_m.c | 226 ++++++++++++++++++++++++++++++++++++++---- + src/target/target.h | 4 + + 2 files changed, 211 insertions(+), 19 deletions(-) + +diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c +index 017a6d3a1..88e9bb299 100644 +--- a/src/target/cortex_m.c ++++ b/src/target/cortex_m.c +@@ -28,6 +28,7 @@ + #include "register.h" + #include "arm_opcodes.h" + #include "arm_semihosting.h" ++#include "smp.h" + #include + #include + +@@ -871,7 +872,7 @@ static int cortex_m_debug_entry(struct target *target) + return ERROR_OK; + } + +-static int cortex_m_poll(struct target *target) ++static int cortex_m_poll_one(struct target *target) + { + int detected_failure = ERROR_OK; + int retval = ERROR_OK; +@@ -934,21 +935,26 @@ static int cortex_m_poll(struct target *target) + + if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) { + retval = cortex_m_debug_entry(target); +- if (retval != ERROR_OK) +- return retval; + +- if (arm_semihosting(target, &retval) != 0) ++ /* arm_semihosting needs to know registers, don't run if debug entry returned error */ ++ if (retval == ERROR_OK && arm_semihosting(target, &retval) != 0) + return retval; + +- target_call_event_callbacks(target, TARGET_EVENT_HALTED); ++ if (target->smp) { ++ LOG_TARGET_DEBUG(target, "postpone target event 'halted'"); ++ target->smp_halt_event_postponed = true; ++ } else { ++ /* regardless of errors returned in previous code update state */ ++ target_call_event_callbacks(target, TARGET_EVENT_HALTED); ++ } + } + if (prev_target_state == TARGET_DEBUG_RUNNING) { + retval = cortex_m_debug_entry(target); +- if (retval != ERROR_OK) +- return retval; + + target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); + } ++ if (retval != ERROR_OK) ++ return retval; + } + + if (target->state == TARGET_UNKNOWN) { +@@ -981,7 +987,104 @@ static int cortex_m_poll(struct target *target) + return retval; + } + +-static int cortex_m_halt(struct target *target) ++static int cortex_m_halt_one(struct target *target); ++ ++static int cortex_m_smp_halt_all(struct list_head *smp_targets) ++{ ++ int retval = ERROR_OK; ++ struct target_list *head; ++ ++ foreach_smp_target(head, smp_targets) { ++ struct target *curr = head->target; ++ if (!target_was_examined(curr)) ++ continue; ++ if (curr->state == TARGET_HALTED) ++ continue; ++ ++ int ret2 = cortex_m_halt_one(curr); ++ if (retval == ERROR_OK) ++ retval = ret2; /* store the first error code ignore others */ ++ } ++ return retval; ++} ++ ++static int cortex_m_smp_post_halt_poll(struct list_head *smp_targets) ++{ ++ int retval = ERROR_OK; ++ struct target_list *head; ++ ++ foreach_smp_target(head, smp_targets) { ++ struct target *curr = head->target; ++ if (!target_was_examined(curr)) ++ continue; ++ /* skip targets that were already halted */ ++ if (curr->state == TARGET_HALTED) ++ continue; ++ ++ int ret2 = cortex_m_poll_one(curr); ++ if (retval == ERROR_OK) ++ retval = ret2; /* store the first error code ignore others */ ++ } ++ return retval; ++} ++ ++static int cortex_m_poll_smp(struct list_head *smp_targets) ++{ ++ int retval = ERROR_OK; ++ struct target_list *head; ++ bool halted = false; ++ ++ foreach_smp_target(head, smp_targets) { ++ struct target *curr = head->target; ++ if (curr->smp_halt_event_postponed) { ++ halted = true; ++ break; ++ } ++ } ++ ++ if (halted) { ++ retval = cortex_m_smp_halt_all(smp_targets); ++ ++ int ret2 = cortex_m_smp_post_halt_poll(smp_targets); ++ if (retval == ERROR_OK) ++ retval = ret2; /* store the first error code ignore others */ ++ ++ foreach_smp_target(head, smp_targets) { ++ struct target *curr = head->target; ++ if (!curr->smp_halt_event_postponed) ++ continue; ++ ++ curr->smp_halt_event_postponed = false; ++ if (curr->state == TARGET_HALTED) { ++ LOG_TARGET_DEBUG(curr, "sending postponed target event 'halted'"); ++ target_call_event_callbacks(curr, TARGET_EVENT_HALTED); ++ } ++ } ++ /* There is no need to set gdb_service->target ++ * as hwthread_update_threads() selects an interesting thread ++ * by its own ++ */ ++ } ++ return retval; ++} ++ ++static int cortex_m_poll(struct target *target) ++{ ++ int retval = cortex_m_poll_one(target); ++ ++ if (target->smp) { ++ struct target_list *last; ++ last = list_last_entry(target->smp_targets, struct target_list, lh); ++ if (target == last->target) ++ /* After the last target in SMP group has been polled ++ * check for postponed halted events and eventually halt and re-poll ++ * other targets */ ++ cortex_m_poll_smp(target->smp_targets); ++ } ++ return retval; ++} ++ ++static int cortex_m_halt_one(struct target *target) + { + LOG_TARGET_DEBUG(target, "target->state: %s", target_state_name(target)); + +@@ -1019,6 +1122,14 @@ static int cortex_m_halt(struct target *target) + return ERROR_OK; + } + ++static int cortex_m_halt(struct target *target) ++{ ++ if (target->smp) ++ return cortex_m_smp_halt_all(target->smp_targets); ++ else ++ return cortex_m_halt_one(target); ++} ++ + static int cortex_m_soft_reset_halt(struct target *target) + { + struct cortex_m_common *cortex_m = target_to_cm(target); +@@ -1096,8 +1207,8 @@ void cortex_m_enable_breakpoints(struct target *target) + } + } + +-static int cortex_m_resume(struct target *target, int current, +- target_addr_t address, int handle_breakpoints, int debug_execution) ++static int cortex_m_restore_one(struct target *target, bool current, ++ target_addr_t *address, bool handle_breakpoints, bool debug_execution) + { + struct armv7m_common *armv7m = target_to_armv7m(target); + struct breakpoint *breakpoint = NULL; +@@ -1105,7 +1216,7 @@ static int cortex_m_resume(struct target *target, int current, + struct reg *r; + + if (target->state != TARGET_HALTED) { +- LOG_TARGET_WARNING(target, "target not halted"); ++ LOG_TARGET_ERROR(target, "target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + +@@ -1147,7 +1258,7 @@ static int cortex_m_resume(struct target *target, int current, + /* current = 1: continue on current pc, otherwise continue at
*/ + r = armv7m->arm.pc; + if (!current) { +- buf_set_u32(r->value, 0, 32, address); ++ buf_set_u32(r->value, 0, 32, *address); + r->dirty = true; + r->valid = true; + } +@@ -1161,8 +1272,12 @@ static int cortex_m_resume(struct target *target, int current, + armv7m_maybe_skip_bkpt_inst(target, NULL); + + resume_pc = buf_get_u32(r->value, 0, 32); ++ if (current) ++ *address = resume_pc; + +- armv7m_restore_context(target); ++ int retval = armv7m_restore_context(target); ++ if (retval != ERROR_OK) ++ return retval; + + /* the front-end may request us not to handle breakpoints */ + if (handle_breakpoints) { +@@ -1172,34 +1287,99 @@ static int cortex_m_resume(struct target *target, int current, + LOG_TARGET_DEBUG(target, "unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")", + breakpoint->address, + breakpoint->unique_id); +- cortex_m_unset_breakpoint(target, breakpoint); +- cortex_m_single_step_core(target); +- cortex_m_set_breakpoint(target, breakpoint); ++ retval = cortex_m_unset_breakpoint(target, breakpoint); ++ if (retval == ERROR_OK) ++ retval = cortex_m_single_step_core(target); ++ int ret2 = cortex_m_set_breakpoint(target, breakpoint); ++ if (retval != ERROR_OK) ++ return retval; ++ if (ret2 != ERROR_OK) ++ return ret2; + } + } + ++ return ERROR_OK; ++} ++ ++static int cortex_m_restart_one(struct target *target, bool debug_execution) ++{ ++ struct armv7m_common *armv7m = target_to_armv7m(target); ++ + /* Restart core */ + cortex_m_set_maskints_for_run(target); + cortex_m_write_debug_halt_mask(target, 0, C_HALT); + + target->debug_reason = DBG_REASON_NOTHALTED; +- + /* registers are now invalid */ + register_cache_invalidate(armv7m->arm.core_cache); + + if (!debug_execution) { + target->state = TARGET_RUNNING; + target_call_event_callbacks(target, TARGET_EVENT_RESUMED); +- LOG_TARGET_DEBUG(target, "target resumed at 0x%" PRIx32 "", resume_pc); + } else { + target->state = TARGET_DEBUG_RUNNING; + target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); +- LOG_TARGET_DEBUG(target, "target debug resumed at 0x%" PRIx32 "", resume_pc); + } + + return ERROR_OK; + } + ++static int cortex_m_restore_smp(struct target *target, bool handle_breakpoints) ++{ ++ struct target_list *head; ++ target_addr_t address; ++ foreach_smp_target(head, target->smp_targets) { ++ struct target *curr = head->target; ++ /* skip calling target */ ++ if (curr == target) ++ continue; ++ if (!target_was_examined(curr)) ++ continue; ++ /* skip running targets */ ++ if (curr->state == TARGET_RUNNING) ++ continue; ++ ++ int retval = cortex_m_restore_one(curr, true, &address, ++ handle_breakpoints, false); ++ if (retval != ERROR_OK) ++ return retval; ++ ++ retval = cortex_m_restart_one(curr, false); ++ if (retval != ERROR_OK) ++ return retval; ++ ++ LOG_TARGET_DEBUG(curr, "SMP resumed at " TARGET_ADDR_FMT, address); ++ } ++ return ERROR_OK; ++} ++ ++static int cortex_m_resume(struct target *target, int current, ++ target_addr_t address, int handle_breakpoints, int debug_execution) ++{ ++ int retval = cortex_m_restore_one(target, !!current, &address, !!handle_breakpoints, !!debug_execution); ++ if (retval != ERROR_OK) { ++ LOG_TARGET_ERROR(target, "context restore failed, aborting resume"); ++ return retval; ++ } ++ ++ if (target->smp && !debug_execution) { ++ retval = cortex_m_restore_smp(target, !!handle_breakpoints); ++ if (retval != ERROR_OK) ++ LOG_WARNING("resume of a SMP target failed, trying to resume current one"); ++ } ++ ++ cortex_m_restart_one(target, !!debug_execution); ++ if (retval != ERROR_OK) { ++ LOG_TARGET_ERROR(target, "resume failed"); ++ return retval; ++ } ++ ++ LOG_TARGET_DEBUG(target, "%sresumed at " TARGET_ADDR_FMT, ++ debug_execution ? "debug " : "", address); ++ ++ return ERROR_OK; ++} ++ + /* int irqstepcount = 0; */ + static int cortex_m_step(struct target *target, int current, + target_addr_t address, int handle_breakpoints) +@@ -1217,6 +1397,11 @@ static int cortex_m_step(struct target *target, int current, + return ERROR_TARGET_NOT_HALTED; + } + ++ /* Just one of SMP cores will step. Set the gdb control ++ * target to current one or gdb miss gdb-end event */ ++ if (target->smp && target->gdb_service) ++ target->gdb_service->target = target; ++ + /* current = 1: continue on current pc, otherwise continue at
*/ + if (!current) { + buf_set_u32(pc->value, 0, 32, address); +@@ -2850,6 +3035,9 @@ static const struct command_registration cortex_m_exec_command_handlers[] = { + .help = "configure software reset handling", + .usage = "['sysresetreq'|'vectreset']", + }, ++ { ++ .chain = smp_command_handlers, ++ }, + COMMAND_REGISTRATION_DONE + }; + static const struct command_registration cortex_m_command_handlers[] = { +diff --git a/src/target/target.h b/src/target/target.h +index d445c2975..ef9ba1062 100644 +--- a/src/target/target.h ++++ b/src/target/target.h +@@ -193,6 +193,10 @@ struct target { + struct list_head *smp_targets; /* list all targets in this smp group/cluster + * The head of the list is shared between the + * cluster, thus here there is a pointer */ ++ bool smp_halt_event_postponed; /* Some SMP implementations (currently Cortex-M) stores ++ * 'halted' events and emits them after all targets of ++ * the SMP group has been polled */ ++ + /* the gdb service is there in case of smp, we have only one gdb server + * for all smp target + * the target attached to the gdb is changing dynamically by changing diff --git a/meta-oe/recipes-devtools/openocd/openocd/0012-flash-nor-rp2040-make-SPI-flash-ID-detection-optiona.patch b/meta-oe/recipes-devtools/openocd/openocd/0012-flash-nor-rp2040-make-SPI-flash-ID-detection-optiona.patch new file mode 100644 index 000000000..7358bfc9a --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0012-flash-nor-rp2040-make-SPI-flash-ID-detection-optiona.patch @@ -0,0 +1,103 @@ +From 0979cbc5bcf0688d10815aaa1b938a6086e75f0e Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sun, 2 Oct 2022 11:21:42 +0200 +Subject: [PATCH] flash/nor/rp2040: make SPI flash ID detection optional + +Do not read ID from SPI flash and suppress autodetection +if non-zero flash bank size is configured. + +Change-Id: Idcf9ee6ca17f9fa89964a60da7bf11e47b4af5e7 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7241 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/rp2040.c | 55 +++++++++++++++++++++++++----------------- + 1 file changed, 33 insertions(+), 22 deletions(-) + +diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c +index feff9a6f9..b0d118bdb 100644 +--- a/src/flash/nor/rp2040.c ++++ b/src/flash/nor/rp2040.c +@@ -50,6 +50,10 @@ struct rp2040_flash_bank { + const struct flash_device *dev; + }; + ++/* guessed SPI flash description if autodetection disabled (same as win w25q16jv) */ ++static const struct flash_device rp2040_default_spi_device = ++ FLASH_ID("autodetect disabled", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0, 0x100, 0x10000, 0); ++ + static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol) + { + uint32_t magic; +@@ -432,41 +436,48 @@ static int rp2040_flash_probe(struct flash_bank *bank) + return err; + } + +- err = rp2040_stack_grab_and_prep(bank); ++ if (bank->size) { ++ /* size overridden, suppress reading SPI flash ID */ ++ priv->dev = &rp2040_default_spi_device; ++ LOG_DEBUG("SPI flash autodetection disabled, using configured size"); + +- uint32_t device_id = 0; +- if (err == ERROR_OK) +- err = rp2040_spi_read_flash_id(target, &device_id); ++ } else { ++ /* zero bank size in cfg, read SPI flash ID and autodetect */ ++ err = rp2040_stack_grab_and_prep(bank); + +- rp2040_finalize_stack_free(bank); ++ uint32_t device_id = 0; ++ if (err == ERROR_OK) ++ err = rp2040_spi_read_flash_id(target, &device_id); + +- if (err != ERROR_OK) +- return err; ++ rp2040_finalize_stack_free(bank); + +- /* search for a SPI flash Device ID match */ +- priv->dev = NULL; +- for (const struct flash_device *p = flash_devices; p->name ; p++) +- if (p->device_id == device_id) { +- priv->dev = p; +- break; ++ if (err != ERROR_OK) ++ return err; ++ ++ /* search for a SPI flash Device ID match */ ++ priv->dev = NULL; ++ for (const struct flash_device *p = flash_devices; p->name ; p++) ++ if (p->device_id == device_id) { ++ priv->dev = p; ++ break; ++ } ++ ++ if (!priv->dev) { ++ LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id); ++ return ERROR_FAIL; + } ++ LOG_INFO("Found flash device '%s' (ID 0x%08" PRIx32 ")", ++ priv->dev->name, priv->dev->device_id); + +- if (!priv->dev) { +- LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id); +- return ERROR_FAIL; ++ bank->size = priv->dev->size_in_bytes; + } + +- LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")", +- priv->dev->name, priv->dev->device_id); +- + /* the Boot ROM flash_range_program() routine requires page alignment */ + bank->write_start_alignment = priv->dev->pagesize; + bank->write_end_alignment = priv->dev->pagesize; + +- bank->size = priv->dev->size_in_bytes; +- + bank->num_sectors = bank->size / priv->dev->sectorsize; +- LOG_INFO("RP2040 B0 Flash Probe: %d bytes @" TARGET_ADDR_FMT ", in %d sectors\n", ++ LOG_INFO("RP2040 B0 Flash Probe: %" PRIu32 " bytes @" TARGET_ADDR_FMT ", in %u sectors\n", + bank->size, bank->base, bank->num_sectors); + bank->sectors = alloc_block_array(0, priv->dev->sectorsize, bank->num_sectors); + if (!bank->sectors) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0013-tcl-target-add-SMP-mode-to-rp2040.cfg.patch b/meta-oe/recipes-devtools/openocd/openocd/0013-tcl-target-add-SMP-mode-to-rp2040.cfg.patch new file mode 100644 index 000000000..0fff6b8b6 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0013-tcl-target-add-SMP-mode-to-rp2040.cfg.patch @@ -0,0 +1,51 @@ +From 8af4d4462fb1954ab4f5d97bc0513e3082a6bb52 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sun, 2 Oct 2022 14:46:11 +0200 +Subject: [PATCH] tcl/target: add SMP mode to rp2040.cfg + +Add the variable selected configuration for SMP debug with rtos hwthread. + +Use SMP by default. + +Change-Id: I1c37d91688a3ab58d65c15686737892965711adc +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7242 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + tcl/target/rp2040.cfg | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/tcl/target/rp2040.cfg b/tcl/target/rp2040.cfg +index ee455420b..0593e03ba 100644 +--- a/tcl/target/rp2040.cfg ++++ b/tcl/target/rp2040.cfg +@@ -26,12 +26,12 @@ if { [info exists CPUTAPID] } { + set _CPUTAPID 0x01002927 + } + +-# Set to '0' or '1' for single core configuration, +-# anything else for isolated debugging of both cores ++# Set to '0' or '1' for single core configuration, 'SMP' for -rtos hwthread ++# handling of both cores, anything else for isolated debugging of both cores + if { [info exists USE_CORE] } { + set _USE_CORE $USE_CORE + } else { +- set _USE_CORE { 0 1 } ++ set _USE_CORE SMP + } + set _BOTH_CORES [expr { $_USE_CORE != 0 && $_USE_CORE != 1 }] + +@@ -54,6 +54,12 @@ if { $_USE_CORE != 0 } { + $_TARGETNAME_1 cortex_m reset_config sysresetreq + } + ++if {[string compare $_USE_CORE SMP] == 0} { ++ $_TARGETNAME_0 configure -rtos hwthread ++ $_TARGETNAME_1 configure -rtos hwthread ++ target smp $_TARGETNAME_0 $_TARGETNAME_1 ++} ++ + if { $_USE_CORE == 1 } { + set _FLASH_TARGET $_TARGETNAME_1 + } else { diff --git a/meta-oe/recipes-devtools/openocd/openocd/0014-tcl-target-remove-rp2040-core0.cfg.patch b/meta-oe/recipes-devtools/openocd/openocd/0014-tcl-target-remove-rp2040-core0.cfg.patch new file mode 100644 index 000000000..e82b5860d --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0014-tcl-target-remove-rp2040-core0.cfg.patch @@ -0,0 +1,83 @@ +From 228fe7300c7df7aa05ba2c0bc19edde6d0156401 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Thu, 3 Nov 2022 10:32:36 +0100 +Subject: [PATCH] tcl/target: remove rp2040-core0.cfg + +rp2040-core0.cfg configuration file was intended for a special adapter +which selects a SWD multidrop target on its own. This means +that rp2040-core0.cfg is totally unusable with a standard SWD +adapter. The file was marked as deprecated in 0.12 release. + +The reworked rp2040.cfg can be restricted to use just one core: + openocd ... -c 'set USE_CORE 0' -f target/rp2040.cfg + +Remove the obsoleted config. + +Change-Id: Id886471622bb4a8cb83f5c4c3660657407aaaf74 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7326 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + tcl/target/rp2040-core0.cfg | 52 ------------------------------------- + 1 file changed, 52 deletions(-) + delete mode 100644 tcl/target/rp2040-core0.cfg + +diff --git a/tcl/target/rp2040-core0.cfg b/tcl/target/rp2040-core0.cfg +deleted file mode 100644 +index 8a111bcbc..000000000 +--- a/tcl/target/rp2040-core0.cfg ++++ /dev/null +@@ -1,52 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-# RP2040 is a microcontroller with dual Cortex-M0+ core. +-# https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html +- +-# The device requires multidrop SWD for debug. +-# This configuration file is intended for a special adapter +-# which selects a multidrop target on its own. +-# Cannot be used with a standard SWD adapter! +- +-echo "Warn : rp2040-core0.cfg configuration file is deprecated and will be" +-echo " removed in the next release. Use following parameters instead:" +-echo " -c 'set USE_CORE 0' -f target/rp2040.cfg" +- +-transport select swd +- +-source [find target/swj-dp.tcl] +- +-if { [info exists CHIPNAME] } { +- set _CHIPNAME $CHIPNAME +-} else { +- set _CHIPNAME rp2040 +-} +- +-if { [info exists WORKAREASIZE] } { +- set _WORKAREASIZE $WORKAREASIZE +-} else { +- set _WORKAREASIZE 0x10000 +-} +- +-if { [info exists CPUTAPID] } { +- set _CPUTAPID $CPUTAPID +-} else { +- set _CPUTAPID 0x01002927 +-} +- +-swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID +-dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu +-set _TARGETNAME $_CHIPNAME.cpu +-target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap +- +-# Backup the work area. The flash probe runs an algorithm on the target CPU. +-# The flash is probed during gdb connect if gdb_memory_map is enabled (by default). +-$_TARGETNAME configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup 1 +- +-set _FLASHNAME $_CHIPNAME.flash +-set _FLASHSIZE 0x200000 +-set _FLASHBASE 0x10000000 +-flash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME +- +-# srst does not exist; use SYSRESETREQ to perform a soft reset +-cortex_m reset_config sysresetreq diff --git a/meta-oe/recipes-devtools/openocd/openocd/0015-riscv-drop-deprecated-command-riscv-set_prefer_sba.patch b/meta-oe/recipes-devtools/openocd/openocd/0015-riscv-drop-deprecated-command-riscv-set_prefer_sba.patch new file mode 100644 index 000000000..282940944 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0015-riscv-drop-deprecated-command-riscv-set_prefer_sba.patch @@ -0,0 +1,71 @@ +From 27edeb775791a598a1e7997fd74078164e771ca6 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 17 Oct 2022 12:28:57 +0200 +Subject: [PATCH] riscv: drop deprecated command 'riscv set_prefer_sba' + +Change-Id: I546efe4e1a6b673b26cfb4a74b5c3809fecda49c +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7271 +Tested-by: jenkins +Reviewed-by: Jan Matyas +--- + src/target/riscv/riscv.c | 39 --------------------------------------- + 1 file changed, 39 deletions(-) + +diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c +index 4f24fb41e..dcd25fa08 100644 +--- a/src/target/riscv/riscv.c ++++ b/src/target/riscv/riscv.c +@@ -2367,37 +2367,6 @@ COMMAND_HANDLER(riscv_set_reset_timeout_sec) + return ERROR_OK; + } + +-COMMAND_HANDLER(riscv_set_prefer_sba) +-{ +- struct target *target = get_current_target(CMD_CTX); +- RISCV_INFO(r); +- bool prefer_sba; +- LOG_WARNING("`riscv set_prefer_sba` is deprecated. Please use `riscv set_mem_access` instead."); +- if (CMD_ARGC != 1) { +- LOG_ERROR("Command takes exactly 1 parameter"); +- return ERROR_COMMAND_SYNTAX_ERROR; +- } +- COMMAND_PARSE_ON_OFF(CMD_ARGV[0], prefer_sba); +- if (prefer_sba) { +- /* Use system bus with highest priority */ +- r->mem_access_methods[0] = RISCV_MEM_ACCESS_SYSBUS; +- r->mem_access_methods[1] = RISCV_MEM_ACCESS_PROGBUF; +- r->mem_access_methods[2] = RISCV_MEM_ACCESS_ABSTRACT; +- } else { +- /* Use progbuf with highest priority */ +- r->mem_access_methods[0] = RISCV_MEM_ACCESS_PROGBUF; +- r->mem_access_methods[1] = RISCV_MEM_ACCESS_SYSBUS; +- r->mem_access_methods[2] = RISCV_MEM_ACCESS_ABSTRACT; +- } +- +- /* Reset warning flags */ +- r->mem_access_progbuf_warn = true; +- r->mem_access_sysbus_warn = true; +- r->mem_access_abstract_warn = true; +- +- return ERROR_OK; +-} +- + COMMAND_HANDLER(riscv_set_mem_access) + { + struct target *target = get_current_target(CMD_CTX); +@@ -2948,14 +2917,6 @@ static const struct command_registration riscv_exec_command_handlers[] = { + .usage = "[sec]", + .help = "Set the wall-clock timeout (in seconds) after reset is deasserted" + }, +- { +- .name = "set_prefer_sba", +- .handler = riscv_set_prefer_sba, +- .mode = COMMAND_ANY, +- .usage = "on|off", +- .help = "When on, prefer to use System Bus Access to access memory. " +- "When off (default), prefer to use the Program Buffer to access memory." +- }, + { + .name = "set_mem_access", + .handler = riscv_set_mem_access, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0016-riscv-drop-deprecated-command-riscv-test_sba_config_.patch b/meta-oe/recipes-devtools/openocd/openocd/0016-riscv-drop-deprecated-command-riscv-test_sba_config_.patch new file mode 100644 index 000000000..ca4e83581 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0016-riscv-drop-deprecated-command-riscv-test_sba_config_.patch @@ -0,0 +1,480 @@ +From f2fc23e16b648c3d5600b5cc44bee69a1e697a3a Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 17 Oct 2022 12:34:23 +0200 +Subject: [PATCH] riscv: drop deprecated command 'riscv test_sba_config_reg' + +Change-Id: I51c1b1cb3de8cb86ee38280fa3f035f6f7a63dbc +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7272 +Reviewed-by: Jan Matyas +Reviewed-by: Tim Newsome +Tested-by: jenkins +--- + src/target/riscv/riscv-013.c | 361 ----------------------------------- + src/target/riscv/riscv.c | 45 ----- + src/target/riscv/riscv.h | 3 - + 3 files changed, 409 deletions(-) + +diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c +index 99d3873de..4e6c8dc36 100644 +--- a/src/target/riscv/riscv-013.c ++++ b/src/target/riscv/riscv-013.c +@@ -65,12 +65,6 @@ static int read_memory(struct target *target, target_addr_t address, + uint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment); + static int write_memory(struct target *target, target_addr_t address, + uint32_t size, uint32_t count, const uint8_t *buffer); +-static int riscv013_test_sba_config_reg(struct target *target, target_addr_t legal_address, +- uint32_t num_words, target_addr_t illegal_address, bool run_sbbusyerror_test); +-static void write_memory_sba_simple(struct target *target, target_addr_t addr, uint32_t *write_data, +- uint32_t write_size, uint32_t sbcs); +-static void read_memory_sba_simple(struct target *target, target_addr_t addr, +- uint32_t *rd_buf, uint32_t read_size, uint32_t sbcs); + + /** + * Since almost everything can be accomplish by scanning the dbus register, all +@@ -2307,7 +2301,6 @@ static int init_target(struct command_context *cmd_ctx, + generic_info->dmi_read = &dmi_read; + generic_info->dmi_write = &dmi_write; + generic_info->read_memory = read_memory; +- generic_info->test_sba_config_reg = &riscv013_test_sba_config_reg; + generic_info->hart_count = &riscv013_hart_count; + generic_info->data_bits = &riscv013_data_bits; + generic_info->print_info = &riscv013_print_info; +@@ -4408,360 +4401,6 @@ void riscv013_fill_dmi_nop_u64(struct target *target, char *buf) + buf_set_u64((unsigned char *)buf, DTM_DMI_ADDRESS_OFFSET, info->abits, 0); + } + +-/* Helper function for riscv013_test_sba_config_reg */ +-static int get_max_sbaccess(struct target *target) +-{ +- RISCV013_INFO(info); +- +- uint32_t sbaccess128 = get_field(info->sbcs, DM_SBCS_SBACCESS128); +- uint32_t sbaccess64 = get_field(info->sbcs, DM_SBCS_SBACCESS64); +- uint32_t sbaccess32 = get_field(info->sbcs, DM_SBCS_SBACCESS32); +- uint32_t sbaccess16 = get_field(info->sbcs, DM_SBCS_SBACCESS16); +- uint32_t sbaccess8 = get_field(info->sbcs, DM_SBCS_SBACCESS8); +- +- if (sbaccess128) +- return 4; +- else if (sbaccess64) +- return 3; +- else if (sbaccess32) +- return 2; +- else if (sbaccess16) +- return 1; +- else if (sbaccess8) +- return 0; +- else +- return -1; +-} +- +-static uint32_t get_num_sbdata_regs(struct target *target) +-{ +- RISCV013_INFO(info); +- +- uint32_t sbaccess128 = get_field(info->sbcs, DM_SBCS_SBACCESS128); +- uint32_t sbaccess64 = get_field(info->sbcs, DM_SBCS_SBACCESS64); +- uint32_t sbaccess32 = get_field(info->sbcs, DM_SBCS_SBACCESS32); +- +- if (sbaccess128) +- return 4; +- else if (sbaccess64) +- return 2; +- else if (sbaccess32) +- return 1; +- else +- return 0; +-} +- +-static int riscv013_test_sba_config_reg(struct target *target, +- target_addr_t legal_address, uint32_t num_words, +- target_addr_t illegal_address, bool run_sbbusyerror_test) +-{ +- LOG_INFO("Testing System Bus Access as defined by RISC-V Debug Spec v0.13"); +- +- uint32_t tests_failed = 0; +- +- uint32_t rd_val; +- uint32_t sbcs_orig; +- int retval = dmi_read(target, &sbcs_orig, DM_SBCS); +- if (retval != ERROR_OK) +- return retval; +- +- uint32_t sbcs = sbcs_orig; +- bool test_passed; +- +- int max_sbaccess = get_max_sbaccess(target); +- +- if (max_sbaccess == -1) { +- LOG_ERROR("System Bus Access not supported in this config."); +- return ERROR_FAIL; +- } +- +- if (get_field(sbcs, DM_SBCS_SBVERSION) != 1) { +- LOG_ERROR("System Bus Access unsupported SBVERSION (%d). Only version 1 is supported.", +- get_field(sbcs, DM_SBCS_SBVERSION)); +- return ERROR_FAIL; +- } +- +- uint32_t num_sbdata_regs = get_num_sbdata_regs(target); +- assert(num_sbdata_regs); +- +- uint32_t rd_buf[num_sbdata_regs]; +- +- /* Test 1: Simple write/read test */ +- test_passed = true; +- sbcs = set_field(sbcs_orig, DM_SBCS_SBAUTOINCREMENT, 0); +- dmi_write(target, DM_SBCS, sbcs); +- +- uint32_t test_patterns[4] = {0xdeadbeef, 0xfeedbabe, 0x12345678, 0x08675309}; +- for (uint32_t sbaccess = 0; sbaccess <= (uint32_t)max_sbaccess; sbaccess++) { +- sbcs = set_field(sbcs, DM_SBCS_SBACCESS, sbaccess); +- dmi_write(target, DM_SBCS, sbcs); +- +- uint32_t compare_mask = (sbaccess == 0) ? 0xff : (sbaccess == 1) ? 0xffff : 0xffffffff; +- +- for (uint32_t i = 0; i < num_words; i++) { +- uint32_t addr = legal_address + (i << sbaccess); +- uint32_t wr_data[num_sbdata_regs]; +- for (uint32_t j = 0; j < num_sbdata_regs; j++) +- wr_data[j] = test_patterns[j] + i; +- write_memory_sba_simple(target, addr, wr_data, num_sbdata_regs, sbcs); +- } +- +- for (uint32_t i = 0; i < num_words; i++) { +- uint32_t addr = legal_address + (i << sbaccess); +- read_memory_sba_simple(target, addr, rd_buf, num_sbdata_regs, sbcs); +- for (uint32_t j = 0; j < num_sbdata_regs; j++) { +- if (((test_patterns[j]+i)&compare_mask) != (rd_buf[j]&compare_mask)) { +- LOG_ERROR("System Bus Access Test 1: Error reading non-autoincremented address %x," +- "expected val = %x, read val = %x", addr, test_patterns[j]+i, rd_buf[j]); +- test_passed = false; +- tests_failed++; +- } +- } +- } +- } +- if (test_passed) +- LOG_INFO("System Bus Access Test 1: Simple write/read test PASSED."); +- +- /* Test 2: Address autoincrement test */ +- target_addr_t curr_addr; +- target_addr_t prev_addr; +- test_passed = true; +- sbcs = set_field(sbcs_orig, DM_SBCS_SBAUTOINCREMENT, 1); +- dmi_write(target, DM_SBCS, sbcs); +- +- for (uint32_t sbaccess = 0; sbaccess <= (uint32_t)max_sbaccess; sbaccess++) { +- sbcs = set_field(sbcs, DM_SBCS_SBACCESS, sbaccess); +- dmi_write(target, DM_SBCS, sbcs); +- +- dmi_write(target, DM_SBADDRESS0, legal_address); +- read_sbcs_nonbusy(target, &sbcs); +- curr_addr = legal_address; +- for (uint32_t i = 0; i < num_words; i++) { +- prev_addr = curr_addr; +- read_sbcs_nonbusy(target, &sbcs); +- curr_addr = sb_read_address(target); +- if ((curr_addr - prev_addr != (uint32_t)(1 << sbaccess)) && (i != 0)) { +- LOG_ERROR("System Bus Access Test 2: Error with address auto-increment, sbaccess = %x.", sbaccess); +- test_passed = false; +- tests_failed++; +- } +- dmi_write(target, DM_SBDATA0, i); +- } +- +- read_sbcs_nonbusy(target, &sbcs); +- +- dmi_write(target, DM_SBADDRESS0, legal_address); +- +- uint32_t val; +- sbcs = set_field(sbcs, DM_SBCS_SBREADONDATA, 1); +- dmi_write(target, DM_SBCS, sbcs); +- dmi_read(target, &val, DM_SBDATA0); /* Dummy read to trigger first system bus read */ +- curr_addr = legal_address; +- for (uint32_t i = 0; i < num_words; i++) { +- prev_addr = curr_addr; +- read_sbcs_nonbusy(target, &sbcs); +- curr_addr = sb_read_address(target); +- if ((curr_addr - prev_addr != (uint32_t)(1 << sbaccess)) && (i != 0)) { +- LOG_ERROR("System Bus Access Test 2: Error with address auto-increment, sbaccess = %x", sbaccess); +- test_passed = false; +- tests_failed++; +- } +- dmi_read(target, &val, DM_SBDATA0); +- read_sbcs_nonbusy(target, &sbcs); +- if (i != val) { +- LOG_ERROR("System Bus Access Test 2: Error reading auto-incremented address," +- "expected val = %x, read val = %x.", i, val); +- test_passed = false; +- tests_failed++; +- } +- } +- } +- if (test_passed) +- LOG_INFO("System Bus Access Test 2: Address auto-increment test PASSED."); +- +- /* Test 3: Read from illegal address */ +- read_memory_sba_simple(target, illegal_address, rd_buf, 1, sbcs_orig); +- +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBERROR) == 2) { +- sbcs = set_field(sbcs_orig, DM_SBCS_SBERROR, 2); +- dmi_write(target, DM_SBCS, sbcs); +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBERROR) == 0) +- LOG_INFO("System Bus Access Test 3: Illegal address read test PASSED."); +- else +- LOG_ERROR("System Bus Access Test 3: Illegal address read test FAILED, unable to clear to 0."); +- } else { +- LOG_ERROR("System Bus Access Test 3: Illegal address read test FAILED, unable to set error code."); +- } +- +- /* Test 4: Write to illegal address */ +- write_memory_sba_simple(target, illegal_address, test_patterns, 1, sbcs_orig); +- +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBERROR) == 2) { +- sbcs = set_field(sbcs_orig, DM_SBCS_SBERROR, 2); +- dmi_write(target, DM_SBCS, sbcs); +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBERROR) == 0) +- LOG_INFO("System Bus Access Test 4: Illegal address write test PASSED."); +- else { +- LOG_ERROR("System Bus Access Test 4: Illegal address write test FAILED, unable to clear to 0."); +- tests_failed++; +- } +- } else { +- LOG_ERROR("System Bus Access Test 4: Illegal address write test FAILED, unable to set error code."); +- tests_failed++; +- } +- +- /* Test 5: Write with unsupported sbaccess size */ +- uint32_t sbaccess128 = get_field(sbcs_orig, DM_SBCS_SBACCESS128); +- +- if (sbaccess128) { +- LOG_INFO("System Bus Access Test 5: SBCS sbaccess error test PASSED, all sbaccess sizes supported."); +- } else { +- sbcs = set_field(sbcs_orig, DM_SBCS_SBACCESS, 4); +- +- write_memory_sba_simple(target, legal_address, test_patterns, 1, sbcs); +- +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBERROR) == 4) { +- sbcs = set_field(sbcs_orig, DM_SBCS_SBERROR, 4); +- dmi_write(target, DM_SBCS, sbcs); +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBERROR) == 0) +- LOG_INFO("System Bus Access Test 5: SBCS sbaccess error test PASSED."); +- else { +- LOG_ERROR("System Bus Access Test 5: SBCS sbaccess error test FAILED, unable to clear to 0."); +- tests_failed++; +- } +- } else { +- LOG_ERROR("System Bus Access Test 5: SBCS sbaccess error test FAILED, unable to set error code."); +- tests_failed++; +- } +- } +- +- /* Test 6: Write to misaligned address */ +- sbcs = set_field(sbcs_orig, DM_SBCS_SBACCESS, 1); +- +- write_memory_sba_simple(target, legal_address+1, test_patterns, 1, sbcs); +- +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBERROR) == 3) { +- sbcs = set_field(sbcs_orig, DM_SBCS_SBERROR, 3); +- dmi_write(target, DM_SBCS, sbcs); +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBERROR) == 0) +- LOG_INFO("System Bus Access Test 6: SBCS address alignment error test PASSED"); +- else { +- LOG_ERROR("System Bus Access Test 6: SBCS address alignment error test FAILED, unable to clear to 0."); +- tests_failed++; +- } +- } else { +- LOG_ERROR("System Bus Access Test 6: SBCS address alignment error test FAILED, unable to set error code."); +- tests_failed++; +- } +- +- /* Test 7: Set sbbusyerror, only run this case in simulation as it is likely +- * impossible to hit otherwise */ +- if (run_sbbusyerror_test) { +- sbcs = set_field(sbcs_orig, DM_SBCS_SBREADONADDR, 1); +- dmi_write(target, DM_SBCS, sbcs); +- +- for (int i = 0; i < 16; i++) +- dmi_write(target, DM_SBDATA0, 0xdeadbeef); +- +- for (int i = 0; i < 16; i++) +- dmi_write(target, DM_SBADDRESS0, legal_address); +- +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBBUSYERROR)) { +- sbcs = set_field(sbcs_orig, DM_SBCS_SBBUSYERROR, 1); +- dmi_write(target, DM_SBCS, sbcs); +- dmi_read(target, &rd_val, DM_SBCS); +- if (get_field(rd_val, DM_SBCS_SBBUSYERROR) == 0) +- LOG_INFO("System Bus Access Test 7: SBCS sbbusyerror test PASSED."); +- else { +- LOG_ERROR("System Bus Access Test 7: SBCS sbbusyerror test FAILED, unable to clear to 0."); +- tests_failed++; +- } +- } else { +- LOG_ERROR("System Bus Access Test 7: SBCS sbbusyerror test FAILED, unable to set error code."); +- tests_failed++; +- } +- } +- +- if (tests_failed == 0) { +- LOG_INFO("ALL TESTS PASSED"); +- return ERROR_OK; +- } else { +- LOG_ERROR("%d TESTS FAILED", tests_failed); +- return ERROR_FAIL; +- } +- +-} +- +-static void write_memory_sba_simple(struct target *target, target_addr_t addr, +- uint32_t *write_data, uint32_t write_size, uint32_t sbcs) +-{ +- RISCV013_INFO(info); +- +- uint32_t rd_sbcs; +- uint32_t masked_addr; +- +- uint32_t sba_size = get_field(info->sbcs, DM_SBCS_SBASIZE); +- +- read_sbcs_nonbusy(target, &rd_sbcs); +- +- uint32_t sbcs_no_readonaddr = set_field(sbcs, DM_SBCS_SBREADONADDR, 0); +- dmi_write(target, DM_SBCS, sbcs_no_readonaddr); +- +- for (uint32_t i = 0; i < sba_size/32; i++) { +- masked_addr = (addr >> 32*i) & 0xffffffff; +- +- if (i != 3) +- dmi_write(target, DM_SBADDRESS0+i, masked_addr); +- else +- dmi_write(target, DM_SBADDRESS3, masked_addr); +- } +- +- /* Write SBDATA registers starting with highest address, since write to +- * SBDATA0 triggers write */ +- for (int i = write_size-1; i >= 0; i--) +- dmi_write(target, DM_SBDATA0+i, write_data[i]); +-} +- +-static void read_memory_sba_simple(struct target *target, target_addr_t addr, +- uint32_t *rd_buf, uint32_t read_size, uint32_t sbcs) +-{ +- RISCV013_INFO(info); +- +- uint32_t rd_sbcs; +- uint32_t masked_addr; +- +- uint32_t sba_size = get_field(info->sbcs, DM_SBCS_SBASIZE); +- +- read_sbcs_nonbusy(target, &rd_sbcs); +- +- uint32_t sbcs_readonaddr = set_field(sbcs, DM_SBCS_SBREADONADDR, 1); +- dmi_write(target, DM_SBCS, sbcs_readonaddr); +- +- /* Write addresses starting with highest address register */ +- for (int i = sba_size/32-1; i >= 0; i--) { +- masked_addr = (addr >> 32*i) & 0xffffffff; +- +- if (i != 3) +- dmi_write(target, DM_SBADDRESS0+i, masked_addr); +- else +- dmi_write(target, DM_SBADDRESS3, masked_addr); +- } +- +- read_sbcs_nonbusy(target, &rd_sbcs); +- +- for (uint32_t i = 0; i < read_size; i++) +- dmi_read(target, &(rd_buf[i]), DM_SBDATA0+i); +-} +- + int riscv013_dmi_write_u64_bits(struct target *target) + { + RISCV013_INFO(info); +diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c +index dcd25fa08..8dafa02b4 100644 +--- a/src/target/riscv/riscv.c ++++ b/src/target/riscv/riscv.c +@@ -2711,38 +2711,6 @@ COMMAND_HANDLER(riscv_dmi_write) + } + } + +-COMMAND_HANDLER(riscv_test_sba_config_reg) +-{ +- LOG_WARNING("Command \"riscv test_sba_config_reg\" is deprecated. " +- "It will be removed in a future OpenOCD version."); +- +- if (CMD_ARGC != 4) { +- LOG_ERROR("Command takes exactly 4 arguments"); +- return ERROR_COMMAND_SYNTAX_ERROR; +- } +- +- struct target *target = get_current_target(CMD_CTX); +- RISCV_INFO(r); +- +- target_addr_t legal_address; +- uint32_t num_words; +- target_addr_t illegal_address; +- bool run_sbbusyerror_test; +- +- COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[0], legal_address); +- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], num_words); +- COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[2], illegal_address); +- COMMAND_PARSE_ON_OFF(CMD_ARGV[3], run_sbbusyerror_test); +- +- if (r->test_sba_config_reg) { +- return r->test_sba_config_reg(target, legal_address, num_words, +- illegal_address, run_sbbusyerror_test); +- } else { +- LOG_ERROR("test_sba_config_reg is not implemented for this target."); +- return ERROR_FAIL; +- } +-} +- + COMMAND_HANDLER(riscv_reset_delays) + { + int wait = 0; +@@ -2982,19 +2950,6 @@ static const struct command_registration riscv_exec_command_handlers[] = { + .usage = "address value", + .help = "Perform a 32-bit DMI write of value at address." + }, +- { +- .name = "test_sba_config_reg", +- .handler = riscv_test_sba_config_reg, +- .mode = COMMAND_ANY, +- .usage = "legal_address num_words " +- "illegal_address run_sbbusyerror_test[on/off]", +- .help = "Perform a series of tests on the SBCS register. " +- "Inputs are a legal, 128-byte aligned address and a number of words to " +- "read/write starting at that address (i.e., address range [legal address, " +- "legal_address+word_size*num_words) must be legally readable/writable), " +- "an illegal, 128-byte aligned address for error flag/handling cases, " +- "and whether sbbusyerror test should be run." +- }, + { + .name = "reset_delays", + .handler = riscv_reset_delays, +diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h +index e7e4c650b..aba0864e6 100644 +--- a/src/target/riscv/riscv.h ++++ b/src/target/riscv/riscv.h +@@ -174,9 +174,6 @@ struct riscv_info { + int (*dmi_read)(struct target *target, uint32_t *value, uint32_t address); + int (*dmi_write)(struct target *target, uint32_t address, uint32_t value); + +- int (*test_sba_config_reg)(struct target *target, target_addr_t legal_address, +- uint32_t num_words, target_addr_t illegal_address, bool run_sbbusyerror_test); +- + int (*sample_memory)(struct target *target, + struct riscv_sample_buf *buf, + riscv_sample_config_t *config, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0017-adapter-Improve-three-adapter-related-prints.patch b/meta-oe/recipes-devtools/openocd/openocd/0017-adapter-Improve-three-adapter-related-prints.patch new file mode 100644 index 000000000..216adcda1 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0017-adapter-Improve-three-adapter-related-prints.patch @@ -0,0 +1,66 @@ +From 30631224da59608d93f56bac0f68acd6c8fd32ac Mon Sep 17 00:00:00 2001 +From: Jan Matyas +Date: Mon, 17 Oct 2022 08:24:05 +0200 +Subject: [PATCH] adapter: Improve three adapter-related prints + +- Do not warn the user about adapter speed not being set + if the selected adapter does not support configurable speed. + This would be confusing to users. + +- Minor reword in the "adapter speed is not selected" warning. + +- Print the adapter name in the "adapter doesn't support + configurable speed" log entry + +- Another minor reword: autoselect --> autoselecting + +Signed-off-by: Jan Matyas +Change-Id: I4c198b547544fd8199921f092153562c5f159134 +Reviewed-on: https://review.openocd.org/c/openocd/+/7269 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/adapter.c | 8 +++++--- + src/transport/transport.c | 2 +- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c +index b7feac575..eb73fcb9a 100644 +--- a/src/jtag/adapter.c ++++ b/src/jtag/adapter.c +@@ -136,9 +136,11 @@ int adapter_init(struct command_context *cmd_ctx) + + int retval; + +- if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) { ++ /* If the adapter supports configurable speed but the speed is not configured, ++ * provide a hint to the user. */ ++ if (adapter_driver->speed && adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) { + LOG_WARNING("An adapter speed is not selected in the init scripts." +- " OpenOCD will try to run the adapter at the low speed (%d kHz)", ++ " OpenOCD will try to run the adapter at very low speed (%d kHz).", + DEFAULT_CLOCK_SPEED_KHZ); + LOG_WARNING("To remove this warnings and achieve reasonable communication speed with the target," + " set \"adapter speed\" or \"jtag_rclk\" in the init scripts."); +@@ -153,7 +155,7 @@ int adapter_init(struct command_context *cmd_ctx) + adapter_config.adapter_initialized = true; + + if (!adapter_driver->speed) { +- LOG_INFO("This adapter doesn't support configurable speed"); ++ LOG_INFO("Note: The adapter \"%s\" doesn't support configurable speed", adapter_driver->name); + return ERROR_OK; + } + +diff --git a/src/transport/transport.c b/src/transport/transport.c +index d72a48baa..c05db3f00 100644 +--- a/src/transport/transport.c ++++ b/src/transport/transport.c +@@ -104,7 +104,7 @@ int allow_transports(struct command_context *ctx, const char * const *vector) + + /* autoselect if there's no choice ... */ + if (!vector[1]) { +- LOG_INFO("only one transport option; autoselect '%s'", vector[0]); ++ LOG_INFO("only one transport option; autoselecting '%s'", vector[0]); + return transport_select(ctx, vector[0]); + } + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0018-flash-stm32l4x-avoid-multiple-assignments.patch b/meta-oe/recipes-devtools/openocd/openocd/0018-flash-stm32l4x-avoid-multiple-assignments.patch new file mode 100644 index 000000000..380c86714 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0018-flash-stm32l4x-avoid-multiple-assignments.patch @@ -0,0 +1,29 @@ +From 66da6f20e4df20511828424d835dfade7dd9d535 Mon Sep 17 00:00:00 2001 +From: Tarek BOCHKATI +Date: Thu, 20 Oct 2022 20:48:48 +0100 +Subject: [PATCH] flash/stm32l4x: avoid multiple assignments + +Change-Id: I6d8e0fbfa7e05f26295fc22733c65c11f7460b51 +Signed-off-by: Tarek BOCHKATI +Reviewed-on: https://review.openocd.org/c/openocd/+/7282 +Reviewed-by: Antonio Borneo +Reviewed-by: Tomas Vanek +Tested-by: jenkins +--- + src/flash/nor/stm32l4x.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c +index 7a6ec3fd2..92d511c17 100644 +--- a/src/flash/nor/stm32l4x.c ++++ b/src/flash/nor/stm32l4x.c +@@ -1740,7 +1740,8 @@ static int stm32l4_probe(struct flash_bank *bank) + + /* Set flash write alignment boundaries. + * Ask the flash infrastructure to ensure required alignment */ +- bank->write_start_alignment = bank->write_end_alignment = stm32l4_info->data_width; ++ bank->write_start_alignment = stm32l4_info->data_width; ++ bank->write_end_alignment = stm32l4_info->data_width; + + /* Initialize the flash registers layout */ + if (part_info->flags & F_HAS_L5_FLASH_REGS) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0019-target-armv7m-Rename-xPSR-to-xpsr.patch b/meta-oe/recipes-devtools/openocd/openocd/0019-target-armv7m-Rename-xPSR-to-xpsr.patch new file mode 100644 index 000000000..1b0343442 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0019-target-armv7m-Rename-xPSR-to-xpsr.patch @@ -0,0 +1,34 @@ +From 11ee500bffe488eba95cea37c99cee6b196e04ff Mon Sep 17 00:00:00 2001 +From: Boris-Chengbiao Zhou +Date: Wed, 26 Oct 2022 03:10:17 +0200 +Subject: [PATCH] target/armv7m: Rename xPSR to xpsr + +The org.gnu.gdb.arm.m-system GDB feature defines the name in lowercase +letters.[1] Not adhering to the definition can cause issues with tools +interacting with the GDB which expect the correct casing. + +[1]: https://sourceware.org/gdb/onlinedocs/gdb/ARM-Features.html + +Change-Id: I0b6584a78f86b053947d79686baad5dac3ec4a00 +Signed-off-by: Boris-Chengbiao Zhou +Reviewed-on: https://review.openocd.org/c/openocd/+/7292 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +Reviewed-by: Antonio Borneo +--- + src/target/armv7m.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/target/armv7m.c b/src/target/armv7m.c +index 1b85315de..5745681d4 100644 +--- a/src/target/armv7m.c ++++ b/src/target/armv7m.c +@@ -97,7 +97,7 @@ static const struct { + { ARMV7M_R13, "sp", 32, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_R14, "lr", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + { ARMV7M_PC, "pc", 32, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.m-profile" }, +- { ARMV7M_XPSR, "xPSR", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, ++ { ARMV7M_XPSR, "xpsr", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, + + { ARMV7M_MSP, "msp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" }, + { ARMV7M_PSP, "psp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0020-flash-nor-numicro-reorder-the-parts-list.patch b/meta-oe/recipes-devtools/openocd/openocd/0020-flash-nor-numicro-reorder-the-parts-list.patch new file mode 100644 index 000000000..47bec1988 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0020-flash-nor-numicro-reorder-the-parts-list.patch @@ -0,0 +1,1395 @@ +From 776e045de0a2ce6644ae19de99820f02628dfbcc Mon Sep 17 00:00:00 2001 +From: Zale Yu +Date: Sun, 6 Nov 2022 22:54:37 +0800 +Subject: [PATCH] flash/nor/numicro: reorder the parts list + +This patch is picked from the flash part of OpenOCD-Nuvoton's commit +("flash: supported Nuvoton M4 series. jtag: Used HW reset instead of +auto reset. tcl: added a configuration file for Nuvoton M4 series.") [1] +It reorders Nuvoton MCU part list and spreads out the way to define the +banks' base address & size of the parts. + +The code comes from the commit basically. Jian-Hong Pan tweaked for the +compatibility with current OpenOCD. So, leave the author as Zale Yu. + +[1]: https://github.com/OpenNuvoton/OpenOCD-Nuvoton/commit/c2d5b8bfc705 + +Signed-off-by: Zale Yu +Signed-off-by: Jian-Hong Pan +Change-Id: I1f21f54dfdf53e5b8ea04d803347d1dbc8c321a0 +Reviewed-on: https://review.openocd.org/c/openocd/+/7339 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/numicro.c | 1347 ++++++++++----------------------------- + 1 file changed, 349 insertions(+), 998 deletions(-) + +diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c +index 1a73eb26d..bafad80ce 100644 +--- a/src/flash/nor/numicro.c ++++ b/src/flash/nor/numicro.c +@@ -12,6 +12,12 @@ + * * + * Copyright (C) 2015 Nemui Trinomius * + * nemuisan_kawausogasuki@live.jp * ++ * * ++ * Copyright (C) 2017 Zale Yu * ++ * CYYU@nuvoton.com * ++ * * ++ * Copyright (C) 2022 Jian-Hong Pan * ++ * chienhung.pan@gmail.com * + ***************************************************************************/ + + #ifdef HAVE_CONFIG_H +@@ -114,1008 +120,353 @@ struct numicro_cpu_type { + struct numicro_flash_bank_type bank[NUMICRO_MAX_FLASH_BANKS]; + }; + +-/* TODO : Support variable DataFlash region for 128kB Flash model */ +-#define NUMICRO_BANKS_NUC100(aprom_size) \ +- .n_banks = 4, \ +- { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \ +- {NUMICRO_CONFIG_BASE, 1024} } +- +-#define NUMICRO_BANKS_M051(aprom_size) \ +- .n_banks = 4, \ +- { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \ +- {NUMICRO_CONFIG_BASE, 1024} } +- +-#define NUMICRO_BANKS_MINI51(aprom_size) \ +- .n_banks = 3, \ +- { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_LDROM_BASE, 2*1024}, {NUMICRO_CONFIG_BASE, 512} } +- +-#define NUMICRO_BANKS_NANO(aprom_size) \ ++/* If DataFlash size equals zero, it means the actual size depends on config settings. */ ++#define NUMICRO_BANKS_GENERAL(aprom_size, data_size, ldrom_size, config_size) \ + .n_banks = 4, \ +- { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \ +- {NUMICRO_CONFIG_BASE, 1024} } +- +-#define NUMICRO_BANKS_NUC400(aprom_size) \ +- .n_banks = 4, \ +- { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 16*1024}, \ +- {NUMICRO_CONFIG_BASE, 1024} } +- ++ {{NUMICRO_APROM_BASE, (aprom_size)}, \ ++ {NUMICRO_DATA_BASE, (data_size)}, \ ++ {NUMICRO_LDROM_BASE, (ldrom_size)}, \ ++ {NUMICRO_CONFIG_BASE, (config_size)}} + + static const struct numicro_cpu_type numicro_parts[] = { + /*PART NO*/ /*PART ID*/ /*Banks*/ +- /* NUC100 Version B */ +- {"NUC100LD2BN", 0x10010004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LD1BN", 0x10010005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LD0BN", 0x10010027, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LC2BN", 0x10010007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100LC1BN", 0x10010008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100LC0BN", 0x10010028, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100LB2BN", 0x10010029, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC100LB1BN", 0x10010030, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC100LB0BN", 0x10010031, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC100LA2BN", 0x10010032, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC100LA1BN", 0x10010033, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC100LA0BN", 0x10010034, NUMICRO_BANKS_NUC100(8*1024)}, +- +- {"NUC100RD2BN", 0x10010013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RD1BN", 0x10010014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RD0BN", 0x10010035, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RC2BN", 0x10010016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RC1BN", 0x10010017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RC0BN", 0x10010036, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RB2BN", 0x10010037, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC100RB1BN", 0x10010038, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC100RB0BN", 0x10010039, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC100RA2BN", 0x10010040, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC100RA1BN", 0x10010041, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC100RA0BN", 0x10010042, NUMICRO_BANKS_NUC100(8*1024)}, +- +- /* NUC100 Version C */ +- {"NUC100LE3CN", 0x20010000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100LE2CN", 0x20010001, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100LE1CN", 0x20010002, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100LD3CN", 0x20010003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LD2CN", 0x20010004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LD1CN", 0x20010005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LC3CN", 0x20010006, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100LC2CN", 0x20010007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100LC1CN", 0x20010008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RE3CN", 0x20010009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100RE2CN", 0x20010010, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100RE1CN", 0x20010011, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100RD3CN", 0x20010012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RD2CN", 0x20010013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RD1CN", 0x20010014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RC3CN", 0x20010015, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RC2CN", 0x20010016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RC1CN", 0x20010017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100VE3CN", 0x20010018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100VE2CN", 0x20010019, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100VE1CN", 0x20010020, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100VD3CN", 0x20010021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100VD2CN", 0x20010022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100VD1CN", 0x20010023, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100VC3CN", 0x20010024, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100VC2CN", 0x20010025, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100VC1CN", 0x20010026, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC100 Version B */ +- {"NUC101YD2BN", 0x10010143, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101YD1BN", 0x10010144, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101YD0BN", 0x10010145, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101YC2BN", 0x10010146, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101YC1BN", 0x10010147, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101YC0BN", 0x10010148, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101YB2BN", 0x10010149, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101YB1BN", 0x10010150, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101YB0BN", 0x10010151, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101YA2BN", 0x10010152, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC101YA1BN", 0x10010153, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC101YA0BN", 0x10010154, NUMICRO_BANKS_NUC100(8*1024)}, +- +- {"NUC101LD2BN", 0x10010104, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LD1BN", 0x10010105, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LD0BN", 0x10010127, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LC2BN", 0x10010107, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101LC1BN", 0x10010108, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101LC0BN", 0x10010128, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101LB2BN", 0x10010129, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101LB1BN", 0x10010130, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101LB0BN", 0x10010131, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101LA2BN", 0x10010132, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC101LA1BN", 0x10010133, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC101LA0BN", 0x10010134, NUMICRO_BANKS_NUC100(8*1024)}, +- +- {"NUC101RD2BN", 0x10010113, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RD1BN", 0x10010114, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RD0BN", 0x10010135, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RC2BN", 0x10010116, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RC1BN", 0x10010117, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RC0BN", 0x10010136, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RB2BN", 0x10010137, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101RB1BN", 0x10010138, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101RB0BN", 0x10010139, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC101RA2BN", 0x10010140, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC101RA1BN", 0x10010141, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC101RA0BN", 0x10010142, NUMICRO_BANKS_NUC100(8*1024)}, +- +- /* NUC101 Version C */ +- {"NUC101LE3CN", 0x20010100, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101LE2CN", 0x20010101, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101LE1CN", 0x20010102, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101LD3CN", 0x20010103, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LD2CN", 0x20010104, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LD1CN", 0x20010105, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LC3CN", 0x20010106, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101LC2CN", 0x20010107, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101LC1CN", 0x20010108, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RE3CN", 0x20010109, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101RE2CN", 0x20010110, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101RE1CN", 0x20010111, NUMICRO_BANKS_NUC100(128*1024)}, +- +- {"NUC101RD3CN", 0x20010112, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RD2CN", 0x20010113, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RD1CN", 0x20010114, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RC3CN", 0x20010115, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RC2CN", 0x20010116, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RC1CN", 0x20010117, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101VE3CN", 0x20010118, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101VE2CN", 0x20010119, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101VE1CN", 0x20010120, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101VD3CN", 0x20010121, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101VD2CN", 0x20010122, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101VD1CN", 0x20010123, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101VC3CN", 0x20010124, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101VC2CN", 0x20010125, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101VC1CN", 0x20010126, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC102 Version A */ +- {"NUC102ZD2AN", 0x00010231, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC102ZC1AN", 0x00010235, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC102LD2AN", 0x00010204, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC102LC1AN", 0x00010208, NUMICRO_BANKS_NUC100(32*1024)}, +- +- {"NUC102RB3AN", 0x00010248, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102RB2AN", 0x00010249, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102RB1AN", 0x00010250, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102RA3AN", 0x00010251, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102RA2AN", 0x00010252, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102RA1AN", 0x00010253, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102VB3AN", 0x00010254, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102VB2AN", 0x00010255, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102VB1AN", 0x00010256, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102VA3AN", 0x00010257, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102VA2AN", 0x00010258, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102VA1AN", 0x00010259, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102LA0AN", 0x00010260, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102LB0AN", 0x00010261, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102LC0AN", 0x00010262, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC102LD0AN", 0x00010263, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC102RA0AN", 0x00010264, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102RB0AN", 0x00010265, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102RC0AN", 0x00010266, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC102RD0AN", 0x00010267, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC102VA0AN", 0x00010268, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102VB0AN", 0x00010269, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102VC0AN", 0x00010270, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC102VD0AN", 0x00010271, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC102ZA0AN", 0x00010272, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC102ZB0AN", 0x00010273, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC102ZC0AN", 0x00010274, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC102ZD0AN", 0x00010275, NUMICRO_BANKS_NUC100(64*1024)}, +- +- /* NUC102 Version A */ +- {"NUC122LD2AN", 0x00012204, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122LD1AN", 0x00012205, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122LC2AN", 0x00012207, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122LC1AN", 0x00012208, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122RD2AN", 0x00012213, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122RD1AN", 0x00012214, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122RC2AN", 0x00012216, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122RC1AN", 0x00012217, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122SD2AN", 0x00012222, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122SD1AN", 0x00012223, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122SC2AN", 0x00012225, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122SC1AN", 0x00012226, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122ZD2AN", 0x00012231, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122ZD1AN", 0x00012232, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122ZC2AN", 0x00012234, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122ZC1AN", 0x00012235, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122ZB2AN", 0x00012237, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122ZB1AN", 0x00012238, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122ZA2AN", 0x00012240, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122ZA1AN", 0x00012241, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122LB2AN", 0x00012243, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122LB1AN", 0x00012244, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122LA2AN", 0x00012246, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122LA1AN", 0x00012247, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122RB2AN", 0x00012249, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122RB1AN", 0x00012250, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122RA2AN", 0x00012252, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122RA1AN", 0x00012253, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122SB2AN", 0x00012255, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122SB1AN", 0x00012256, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122SA2AN", 0x00012258, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122SA1AN", 0x00012259, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122LA0AN", 0x00012260, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122LB0AN", 0x00012261, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122LC0AN", 0x00012262, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122LD0AN", 0x00012263, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122RA0AN", 0x00012264, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122RB0AN", 0x00012265, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122RC0AN", 0x00012266, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122RD0AN", 0x00012267, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122SA0AN", 0x00012268, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122SB0AN", 0x00012269, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122SC0AN", 0x00012270, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122SD0AN", 0x00012271, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122ZA0AN", 0x00012272, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122ZB0AN", 0x00012273, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122ZC0AN", 0x00012274, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122ZD0AN", 0x00012275, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122YD2AN", 0x00012277, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122YD1AN", 0x00012278, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122YD0AN", 0x00012279, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC122YC2AN", 0x00012281, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122YC1AN", 0x00012282, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122YC0AN", 0x00012283, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC122YB2AN", 0x00012285, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122YB1AN", 0x00012286, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122YB0AN", 0x00012287, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC122YA2AN", 0x00012289, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122YA1AN", 0x00012290, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC122YA0AN", 0x00012291, NUMICRO_BANKS_NUC100(8*1024)}, +- +- /* NUC120 Version C */ +- {"NUC120LD2BN", 0x10012004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LD1BN", 0x10012005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LD0BN", 0x10012027, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LC2BN", 0x10012007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120LC1BN", 0x10012008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120LC0BN", 0x10012028, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120LB2BN", 0x10012029, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC120LB1BN", 0x10012030, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC120LB0BN", 0x10012031, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC120LA2BN", 0x10012032, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC120LA1BN", 0x10012033, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC120LA0BN", 0x10012034, NUMICRO_BANKS_NUC100(8*1024)}, +- +- {"NUC120RD2BN", 0x10012013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RD1BN", 0x10012014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RD0BN", 0x10012035, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RC2BN", 0x10012016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RC1BN", 0x10012017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RC0BN", 0x10012036, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RB2BN", 0x10012037, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC120RB1BN", 0x10012038, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC120RB0BN", 0x10012039, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC120RA2BN", 0x10012040, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC120RA1BN", 0x10012041, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC120RA0BN", 0x10012042, NUMICRO_BANKS_NUC100(8*1024)}, +- +- /* NUC120 Version C */ +- {"NUC120LE3CN", 0x20012000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120LE2CN", 0x20012001, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120LE1CN", 0x20012002, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120LD3CN", 0x20012003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LD2CN", 0x20012004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LD1CN", 0x20012005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LC3CN", 0x20012006, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120LC2CN", 0x20012007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120LC1CN", 0x20012008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RE3CN", 0x20012009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120RE2CN", 0x20012010, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120RE1CN", 0x20012011, NUMICRO_BANKS_NUC100(128*1024)}, +- +- {"NUC120RD3CN", 0x20012012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RD2CN", 0x20012013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RD1CN", 0x20012014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RC3CN", 0x20012015, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RC2CN", 0x20012016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RC1CN", 0x20012017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120VE3CN", 0x20012018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120VE2CN", 0x20012019, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120VE1CN", 0x20012020, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120VD3CN", 0x20012021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120VD2CN", 0x20012022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120VD1CN", 0x20012023, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120VC3CN", 0x20012024, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120VC2CN", 0x20012025, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120VC1CN", 0x20012026, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC120 Version B */ +- {"NUC130LD2BN", 0x10013004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LD1BN", 0x10013005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LD0BN", 0x10013027, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LC2BN", 0x10013007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130LC1BN", 0x10013008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130LC0BN", 0x10013028, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130LB2BN", 0x10013029, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC130LB1BN", 0x10013030, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC130LB0BN", 0x10013031, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC130LA2BN", 0x10013032, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC130LA1BN", 0x10013033, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC130LA0BN", 0x10013034, NUMICRO_BANKS_NUC100(8*1024)}, +- +- {"NUC130RD2BN", 0x10013013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RD1BN", 0x10013014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RD0BN", 0x10013035, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RC2BN", 0x10013016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RC1BN", 0x10013017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RC0BN", 0x10013036, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RB2BN", 0x10013037, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC130RB1BN", 0x10013038, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC130RB0BN", 0x10013039, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC130RA2BN", 0x10013040, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC130RA1BN", 0x10013041, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC130RA0BN", 0x10013042, NUMICRO_BANKS_NUC100(8*1024)}, +- +- /* NUC130 Version C */ +- {"NUC130LE3CN", 0x20013000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130LE2CN", 0x20013001, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130LE1CN", 0x20013002, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130LD3CN", 0x20013003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LD2CN", 0x20013004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LD1CN", 0x20013005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LC3CN", 0x20013006, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130LC2CN", 0x20013007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130LC1CN", 0x20013008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RE3CN", 0x20013009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130RE2CN", 0x20013010, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130RE1CN", 0x20013011, NUMICRO_BANKS_NUC100(128*1024)}, +- +- {"NUC130RD3CN", 0x20013012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RD2CN", 0x20013013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RD1CN", 0x20013014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RC3CN", 0x20013015, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RC2CN", 0x20013016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RC1CN", 0x20013017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130VE3CN", 0x20013018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130VE2CN", 0x20013019, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130VE1CN", 0x20013020, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130VD3CN", 0x20013021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130VD2CN", 0x20013022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130VD1CN", 0x20013023, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130VC3CN", 0x20013024, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130VC2CN", 0x20013025, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130VC1CN", 0x20013026, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC140 Version B */ +- {"NUC140LD2BN", 0x10014004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LD1BN", 0x10014005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LD0BN", 0x10014027, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LC2BN", 0x10014007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140LC1BN", 0x10014008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140LC0BN", 0x10014028, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140LB2BN", 0x10014029, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC140LB1BN", 0x10014030, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC140LB0BN", 0x10014031, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC140LA2BN", 0x10014032, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC140LA1BN", 0x10014033, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC140LA0BN", 0x10014034, NUMICRO_BANKS_NUC100(8*1024)}, +- +- {"NUC140RD2BN", 0x10014013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RD1BN", 0x10014014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RD0BN", 0x10014035, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RC2BN", 0x10014016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RC1BN", 0x10014017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RC0BN", 0x10014036, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RB2BN", 0x10014037, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC140RB1BN", 0x10014038, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC140RB0BN", 0x10014039, NUMICRO_BANKS_NUC100(16*1024)}, +- {"NUC140RA2BN", 0x10014040, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC140RA1BN", 0x10014041, NUMICRO_BANKS_NUC100(8*1024)}, +- {"NUC140RA0BN", 0x10014042, NUMICRO_BANKS_NUC100(8*1024)}, +- +- /* NUC140 Version C */ +- {"NUC140LE3CN", 0x20014000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140LE2CN", 0x20014001, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140LE1CN", 0x20014002, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140LD3CN", 0x20014003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LD2CN", 0x20014004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LD1CN", 0x20014005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LC3CN", 0x20014006, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140LC2CN", 0x20014007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140LC1CN", 0x20014008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RE3CN", 0x20014009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140RE2CN", 0x20014010, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140RE1CN", 0x20014011, NUMICRO_BANKS_NUC100(128*1024)}, +- +- {"NUC140RD3CN", 0x20014012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RD2CN", 0x20014013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RD1CN", 0x20014014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RC3CN", 0x20014015, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RC2CN", 0x20014016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RC1CN", 0x20014017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140VE3CN", 0x20014018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140VE2CN", 0x20014019, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140VE1CN", 0x20014020, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140VD3CN", 0x20014021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140VD2CN", 0x20014022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140VD1CN", 0x20014023, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140VC3CN", 0x20014024, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140VC2CN", 0x20014025, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140VC1CN", 0x20014026, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC100 Version A */ +- {"NUC100LE3AN", 0x00010000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100LE2AN", 0x00010001, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100LE1AN", 0x00010002, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100LD3AN", 0x00010003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LD2AN", 0x00010004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LD1AN", 0x00010005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LC3AN", 0x00010006, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100LC2AN", 0x00010007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100LC1AN", 0x00010008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RE3AN", 0x00010009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100RE2AN", 0x00010010, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100RE1AN", 0x00010011, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100RD3AN", 0x00010012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RD2AN", 0x00010013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RD1AN", 0x00010014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RC3AN", 0x00010015, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RC2AN", 0x00010016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RC1AN", 0x00010017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100VE3AN", 0x00010018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100VE2AN", 0x00010019, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100VE1AN", 0x00010020, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100VD3AN", 0x00010021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100VD2AN", 0x00010022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100VD1AN", 0x00010023, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100VC3AN", 0x00010024, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100VC2AN", 0x00010025, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100VC1AN", 0x00010026, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC100 Version A */ +- {"NUC101LE3AN", 0x00010100, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101LE2AN", 0x00010101, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101LE1AN", 0x00010102, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101LD3AN", 0x00010103, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LD2AN", 0x00010104, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LD1AN", 0x00010105, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101LC3AN", 0x00010106, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101LC2AN", 0x00010107, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101LC1AN", 0x00010108, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RE3AN", 0x00010109, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101RE2AN", 0x00010110, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101RE1AN", 0x00010111, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101RD3AN", 0x00010112, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RD2AN", 0x00010113, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RD1AN", 0x00010114, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101RC3AN", 0x00010115, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RC2AN", 0x00010116, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101RC1AN", 0x00010117, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101VE3AN", 0x00010118, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101VE2AN", 0x00010119, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101VE1AN", 0x00010120, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC101VD3AN", 0x00010121, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101VD2AN", 0x00010122, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101VD1AN", 0x00010123, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC101VC3AN", 0x00010124, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101VC2AN", 0x00010125, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC101VC1AN", 0x00010126, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC120 Version A */ +- {"NUC120LE3AN", 0x00012000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120LE2AN", 0x00012001, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120LE1AN", 0x00012002, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120LD3AN", 0x00012003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LD2AN", 0x00012004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LD1AN", 0x00012005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LC3AN", 0x00012006, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120LC2AN", 0x00012007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120LC1AN", 0x00012008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RE3AN", 0x00012009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120RE2AN", 0x00012010, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120RE1AN", 0x00012011, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120RD3AN", 0x00012012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RD2AN", 0x00012013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RD1AN", 0x00012014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RC3AN", 0x00012015, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RC2AN", 0x00012016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RC1AN", 0x00012017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120VE3AN", 0x00012018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120VE2AN", 0x00012019, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120VE1AN", 0x00012020, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120VD3AN", 0x00012021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120VD2AN", 0x00012022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120VD1AN", 0x00012023, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120VC3AN", 0x00012024, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120VC2AN", 0x00012025, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120VC1AN", 0x00012026, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC120 Version A */ +- {"NUC130LE3AN", 0x00013000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130LE2AN", 0x00013001, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130LE1AN", 0x00013002, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130LD3AN", 0x00013003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LD2AN", 0x00013004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LD1AN", 0x00013005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130LC3AN", 0x00013006, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130LC2AN", 0x00013007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130LC1AN", 0x00013008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RE3AN", 0x00013009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130RE2AN", 0x00013010, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130RE1AN", 0x00013011, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130RD3AN", 0x00013012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RD2AN", 0x00013013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RD1AN", 0x00013014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130RC3AN", 0x00013015, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RC2AN", 0x00013016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130RC1AN", 0x00013017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130VE3AN", 0x00013018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130VE2AN", 0x00013019, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130VE1AN", 0x00013020, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130VD3AN", 0x00013021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130VD2AN", 0x00013022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130VD1AN", 0x00013023, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC130VC3AN", 0x00013024, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130VC2AN", 0x00013025, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC130VC1AN", 0x00013026, NUMICRO_BANKS_NUC100(32*1024)}, +- +- /* NUC140 Version A */ +- {"NUC140LE3AN", 0x00014000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140LE2AN", 0x00014001, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140LE1AN", 0x00014002, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140LD3AN", 0x00014003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LD2AN", 0x00014004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LD1AN", 0x00014005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140LC3AN", 0x00014006, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140LC2AN", 0x00014007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140LC1AN", 0x00014008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RE3AN", 0x00014009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140RE2AN", 0x00014010, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140RE1AN", 0x00014011, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140RD3AN", 0x00014012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RD2AN", 0x00014013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RD1AN", 0x00014014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140RC3AN", 0x00014015, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RC2AN", 0x00014016, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140RC1AN", 0x00014017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140VE3AN", 0x00014018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140VE2AN", 0x00014019, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140VE1AN", 0x00014020, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC140VD3AN", 0x00014021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140VD2AN", 0x00014022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140VD1AN", 0x00014023, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC140VC3AN", 0x00014024, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140VC2AN", 0x00014025, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC140VC1AN", 0x00014026, NUMICRO_BANKS_NUC100(32*1024)}, +- +- +- /* M052 */ +- {"M052LAN" , 0x00005200, NUMICRO_BANKS_M051(8*1024)}, +- {"M052PAN" , 0x00005201, NUMICRO_BANKS_M051(8*1024)}, +- {"M052YAN" , 0x00005202, NUMICRO_BANKS_M051(8*1024)}, +- {"M052ZAN" , 0x00005203, NUMICRO_BANKS_M051(8*1024)}, +- +- /* M054 */ +- {"M054LAN" , 0x00005400, NUMICRO_BANKS_M051(16*1024)}, +- {"M054PAN" , 0x00005401, NUMICRO_BANKS_M051(16*1024)}, +- {"M054YAN" , 0x00005402, NUMICRO_BANKS_M051(16*1024)}, +- {"M054ZAN" , 0x00005403, NUMICRO_BANKS_M051(16*1024)}, +- +- /* M058 */ +- {"M058LAN" , 0x00005800, NUMICRO_BANKS_M051(32*1024)}, +- {"M058PAN" , 0x00005801, NUMICRO_BANKS_M051(32*1024)}, +- {"M058YAN" , 0x00005802, NUMICRO_BANKS_M051(32*1024)}, +- {"M058ZAN" , 0x00005803, NUMICRO_BANKS_M051(32*1024)}, +- +- /* M0516 */ +- {"M0516LAN" , 0x00005A00, NUMICRO_BANKS_M051(64*1024)}, +- {"M0516PAN" , 0x00005A01, NUMICRO_BANKS_M051(64*1024)}, +- {"M0516YAN" , 0x00005A02, NUMICRO_BANKS_M051(64*1024)}, +- {"M0516ZAN" , 0x00005A03, NUMICRO_BANKS_M051(64*1024)}, +- {"M051LBN" , 0x10005100, NUMICRO_BANKS_M051(4*1024)}, +- {"M051PBN" , 0x10005101, NUMICRO_BANKS_M051(4*1024)}, +- {"M051YBN" , 0x10005102, NUMICRO_BANKS_M051(4*1024)}, +- {"M051ZBN" , 0x10005103, NUMICRO_BANKS_M051(4*1024)}, +- {"M052LBN" , 0x10005200, NUMICRO_BANKS_M051(8*1024)}, +- {"M052PBN" , 0x10005201, NUMICRO_BANKS_M051(8*1024)}, +- {"M052YBN" , 0x10005202, NUMICRO_BANKS_M051(8*1024)}, +- {"M052ZBN" , 0x10005203, NUMICRO_BANKS_M051(8*1024)}, +- {"M054LBN" , 0x10005400, NUMICRO_BANKS_M051(16*1024)}, +- {"M054PBN" , 0x10005401, NUMICRO_BANKS_M051(16*1024)}, +- {"M054YBN" , 0x10005402, NUMICRO_BANKS_M051(16*1024)}, +- {"M054ZBN" , 0x10005403, NUMICRO_BANKS_M051(16*1024)}, +- {"M058LBN" , 0x10005800, NUMICRO_BANKS_M051(32*1024)}, +- {"M058PBN" , 0x10005801, NUMICRO_BANKS_M051(32*1024)}, +- {"M058YBN" , 0x10005802, NUMICRO_BANKS_M051(32*1024)}, +- {"M058ZBN" , 0x10005803, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516LBN" , 0x10005A00, NUMICRO_BANKS_M051(64*1024)}, +- {"M0516PBN" , 0x10005A01, NUMICRO_BANKS_M051(64*1024)}, +- {"M0516YBN" , 0x10005A02, NUMICRO_BANKS_M051(64*1024)}, +- {"M0516ZBN" , 0x10005A03, NUMICRO_BANKS_M051(64*1024)}, +- {"M052LDN" , 0x20005200, NUMICRO_BANKS_M051(8*1024)}, +- {"M054LDN" , 0x20005400, NUMICRO_BANKS_M051(16*1024)}, +- {"M058LDN" , 0x20005800, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516LDN" , 0x20005A00, NUMICRO_BANKS_M051(64*1024)}, +- {"M052ZDN" , 0x20005203, NUMICRO_BANKS_M051(8*1024)}, +- {"M054ZDN" , 0x20005403, NUMICRO_BANKS_M051(16*1024)}, +- {"M058ZDN" , 0x20005803, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516ZDN" , 0x20005A03, NUMICRO_BANKS_M051(64*1024)}, +- {"M052TDN" , 0x20005204, NUMICRO_BANKS_M051(8*1024)}, +- {"M054TDN" , 0x20005404, NUMICRO_BANKS_M051(16*1024)}, +- {"M058TDN" , 0x20005804, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516TDN" , 0x20005A04, NUMICRO_BANKS_M051(64*1024)}, +- {"M052XDN" , 0x20005205, NUMICRO_BANKS_M051(8*1024)}, +- {"M054XDN" , 0x20005405, NUMICRO_BANKS_M051(16*1024)}, +- {"M058XDN" , 0x20005805, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516XDN" , 0x20005A05, NUMICRO_BANKS_M051(64*1024)}, +- {"M052LDE" , 0x30005200, NUMICRO_BANKS_M051(8*1024)}, +- {"M054LDE" , 0x30005400, NUMICRO_BANKS_M051(16*1024)}, +- {"M058LDE" , 0x30005800, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516LDE" , 0x30005A00, NUMICRO_BANKS_M051(64*1024)}, +- {"M052ZDE" , 0x30005203, NUMICRO_BANKS_M051(8*1024)}, +- {"M054ZDE" , 0x30005403, NUMICRO_BANKS_M051(16*1024)}, +- {"M058ZDE" , 0x30005803, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516ZDE" , 0x30005A03, NUMICRO_BANKS_M051(64*1024)}, +- {"M052TDE" , 0x30005204, NUMICRO_BANKS_M051(8*1024)}, +- {"M054TDE" , 0x30005404, NUMICRO_BANKS_M051(16*1024)}, +- {"M058TDE" , 0x30005804, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516TDE" , 0x30005A04, NUMICRO_BANKS_M051(64*1024)}, +- {"M052XDE" , 0x30005205, NUMICRO_BANKS_M051(8*1024)}, +- {"M054XDE" , 0x30005405, NUMICRO_BANKS_M051(16*1024)}, +- {"M058XDE" , 0x30005805, NUMICRO_BANKS_M051(32*1024)}, +- {"M0516XDE" , 0x30005A05, NUMICRO_BANKS_M051(64*1024)}, +- +- /* Mini51 */ +- {"MINI51LAN", 0x00205100, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51QAN", 0x00205101, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51 ", 0x00205102, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51ZAN", 0x00205103, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51TAN", 0x00205104, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI52LAN", 0x00205200, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52QAN", 0x00205201, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52 ", 0x00205202, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52ZAN", 0x00205203, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52TAN", 0x00205204, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI54LAN", 0x00205400, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54QAN", 0x00205401, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54 ", 0x00205402, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54ZAN", 0x00205403, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54TAN", 0x00205404, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI51LBN", 0x10205100, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51QBN", 0x10205101, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51 ", 0x10205102, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51ZBN", 0x10205103, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51TBN", 0x10205104, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI52LBN", 0x10205200, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52QBN", 0x10205201, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52 ", 0x10205202, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52ZBN", 0x10205203, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52TBN", 0x10205204, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI54LBN", 0x10205400, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54QBN", 0x10205401, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54 ", 0x10205402, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54ZBN" , 0x10205403, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54TBN" , 0x10205404, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI51LDE" , 0x20205100, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51QDE" , 0x20205101, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51 " , 0x20205102, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51ZDE" , 0x20205103, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51TDE" , 0x20205104, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI51FDE" , 0x20205105, NUMICRO_BANKS_MINI51(4*1024)}, +- {"MINI52LDE" , 0x20205200, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52QDE" , 0x20205201, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52 " , 0x20205202, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52ZDE" , 0x20205203, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52TDE" , 0x20205204, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI52FDE" , 0x20205205, NUMICRO_BANKS_MINI51(8*1024)}, +- {"MINI54LDE" , 0x20205400, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54QDE" , 0x20205401, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54 " , 0x20205402, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54ZDE" , 0x20205403, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54TDE" , 0x20205404, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI54FDE" , 0x20205405, NUMICRO_BANKS_MINI51(16*1024)}, +- {"MINI55LDE" , 0x20205500, NUMICRO_BANKS_MINI51(16*1024)}, +- +- /* NANO100 */ +- {"NANO100VF3AN" , 0x00110000, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO100VF2AN" , 0x00110001, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO100RF3AN" , 0x00110002, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO100RF2AN" , 0x00110003, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO100LF3AN" , 0x00110004, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO100LF2AN" , 0x00110005, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO100VE3AN" , 0x00110006, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100VE2AN" , 0x00110007, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100RE3AN" , 0x00110008, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100RE2AN" , 0x00110009, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100LE3AN" , 0x00110010, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100LE2AN" , 0x00110011, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100VD3AN" , 0x00110012, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100VD2AN" , 0x00110013, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100VD1AN" , 0x00110014, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100RD3AN" , 0x00110015, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100RD2AN" , 0x00110016, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100RD1AN" , 0x00110017, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100LD3AN" , 0x00110018, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100LD2AN" , 0x00110019, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100LD1AN" , 0x00110020, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100VC2AN" , 0x00110021, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100VC1AN" , 0x00110022, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100RC2AN" , 0x00110023, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100RC1AN" , 0x00110024, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100LC2AN" , 0x00110025, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100LC1AN" , 0x00110026, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100VB1AN" , 0x00110027, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO100VB0AN" , 0x00110028, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO100RB1AN" , 0x00110029, NUMICRO_BANKS_NANO(16*1024)}, +- +- {"NANO110VF3AN" , 0x00111000, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO110VF2AN" , 0x00111001, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO110RF3AN" , 0x00111002, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO110RF2AN" , 0x00111003, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO110VE3AN" , 0x00111006, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110VE2AN" , 0x00111007, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110RE3AN" , 0x00111008, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110RE2AN" , 0x00111009, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110VD3AN" , 0x00111012, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110VD2AN" , 0x00111013, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110VD1AN" , 0x00111014, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110RD3AN" , 0x00111015, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110RD2AN" , 0x00111016, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110RD1AN" , 0x00111017, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110VC2AN" , 0x00111021, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO110VC1AN" , 0x00111022, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO110SC2AN" , 0x00111023, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO110SC1AN" , 0x00111024, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120VF3AN" , 0x00112000, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO120VF2AN" , 0x00112001, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO120RF3AN" , 0x00112002, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO120RF2AN" , 0x00112003, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO120LF3AN" , 0x00112004, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO120LF2AN" , 0x00112005, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO120VE3AN" , 0x00112006, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120VE2AN" , 0x00112007, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120RE3AN" , 0x00112008, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120RE2AN" , 0x00112009, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120LE3AN" , 0x00112010, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120LE2AN" , 0x00112011, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120VD3AN" , 0x00112012, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120VD2AN" , 0x00112013, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120VD1AN" , 0x00112014, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120SD3AN" , 0x00112015, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120SD2AN" , 0x00112016, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120SD1AN" , 0x00112017, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120LD3AN" , 0x00112018, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120LD2AN" , 0x00112019, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120LD1AN" , 0x00112020, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120VC2AN" , 0x00112021, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120VC1AN" , 0x00112022, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120SC2AN" , 0x00112023, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120SC1AN" , 0x00112024, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120LC2AN" , 0x00112025, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120LC1AN" , 0x00112026, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO130VF3AN" , 0x00113000, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO130VF2AN" , 0x00113001, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO130SF3AN" , 0x00113002, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO130SF2AN" , 0x00113003, NUMICRO_BANKS_NANO(256*1024)}, +- {"NANO130VE3AN" , 0x00113006, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO130VE2AN" , 0x00113007, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO130SE3AN" , 0x00113008, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO130SE2AN" , 0x00113009, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO130VD3AN" , 0x00113012, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130VD2AN" , 0x00113013, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130VD1AN" , 0x00113014, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130SD3AN" , 0x00113015, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130SD2AN" , 0x00113016, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130SD1AN" , 0x00113017, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130VC2AN" , 0x00113021, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO130VC1AN" , 0x00113022, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO130SC2AN" , 0x00113023, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO130SC1AN" , 0x00113024, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100KE3BN" , 0x00110030, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100KE2BN" , 0x00110031, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100VE3BN" , 0x00110032, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100VE2BN" , 0x00110033, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100SE3BN" , 0x00110034, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100SE2BN" , 0x00110035, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100LE3BN" , 0x00110036, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100LE2BN" , 0x00110037, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO100KD3BN" , 0x00110038, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100KD2BN" , 0x00110039, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100VD3BN" , 0x0011003A, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100VD2BN" , 0x0011003B, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100SD3BN" , 0x0011003C, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100SD2BN" , 0x0011003D, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100LD3BN" , 0x0011003E, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100LD2BN" , 0x0011003F, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO100KC2BN" , 0x00110040, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100VC2BN" , 0x00110041, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100SC2BN" , 0x00110042, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO100LC2BN" , 0x00110043, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO110KE3BN" , 0x00111030, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110KE2BN" , 0x00111031, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110VE3BN" , 0x00111032, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110VE2BN" , 0x00111033, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110SE3BN" , 0x00111034, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110SE2BN" , 0x00111035, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110KD3BN" , 0x00111038, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110KD2BN" , 0x00111039, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110VD3BN" , 0x0011103A, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110VD2BN" , 0x0011103B, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110SD3BN" , 0x0011103C, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110SD2BN" , 0x0011103D, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO110KC2BN" , 0x00111040, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO110VC2BN" , 0x00111041, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO110SC2BN" , 0x00111042, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120KE3BN" , 0x00112030, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120KE2BN" , 0x00112031, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120VE3BN" , 0x00112032, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120VE2BN" , 0x00112033, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120SE3BN" , 0x00112034, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120SE2BN" , 0x00112035, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120LE3BN" , 0x00112036, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120LE2BN" , 0x00112037, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO120KD3BN" , 0x00112038, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120KD2BN" , 0x00112039, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120VD3BN" , 0x0011203A, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120VD2BN" , 0x0011203B, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120SD3BN" , 0x0011203C, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120SD2BN" , 0x0011203D, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120LD3BN" , 0x0011203E, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120LD2BN" , 0x0011203F, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO120KC2BN" , 0x00112040, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120VC2BN" , 0x00112041, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120SC2BN" , 0x00112042, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO120LC2BN" , 0x00112043, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO130KE3BN" , 0x00113030, NUMICRO_BANKS_NANO(123*1024)}, +- {"NANO130KE2BN" , 0x00113031, NUMICRO_BANKS_NANO(123*1024)}, +- {"NANO130VE3BN" , 0x00113032, NUMICRO_BANKS_NANO(123*1024)}, +- {"NANO130VE2BN" , 0x00113033, NUMICRO_BANKS_NANO(123*1024)}, +- {"NANO130SE3BN" , 0x00113034, NUMICRO_BANKS_NANO(123*1024)}, +- {"NANO130SE2BN" , 0x00113035, NUMICRO_BANKS_NANO(123*1024)}, +- {"NANO130KD3BN" , 0x00113038, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130KD2BN" , 0x00113039, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130VD3BN" , 0x0011303A, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130VD2BN" , 0x0011303B, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130SD3BN" , 0x0011303C, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130SD2BN" , 0x0011303D, NUMICRO_BANKS_NANO(64*1024)}, +- {"NANO130KC2BN" , 0x00113040, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO130VC2BN" , 0x00113041, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO130SC2BN" , 0x00113042, NUMICRO_BANKS_NANO(32*1024)}, +- {"N512DC4" , 0x00100000, NUMICRO_BANKS_NANO(64*1024)}, +- {"N512LC4" , 0x00100001, NUMICRO_BANKS_NANO(64*1024)}, +- {"N512MC4" , 0x00100003, NUMICRO_BANKS_NANO(64*1024)}, +- +- {"N512SC4" , 0x00100005, NUMICRO_BANKS_NANO(64*1024)}, +- {"N512VD4" , 0x00100008, NUMICRO_BANKS_NANO(128*1024)}, +- {"N512MD4" , 0x00100009, NUMICRO_BANKS_NANO(128*1024)}, +- {"N512SD4" , 0x00100010, NUMICRO_BANKS_NANO(128*1024)}, +- {"NANO110RC2BN" , 0x00111043, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO110RD3BN" , 0x00111045, NUMICRO_BANKS_NANO(64*1024)}, +- {"TX110VE3BN" , 0x00111036, NUMICRO_BANKS_NANO(128*1024)}, +- +- /* NANO102/NANO112 */ +- {"NANO112LB0AN" , 0x00111201, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO112LB1AN" , 0x00111202, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO112LC1AN" , 0x00111203, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO112LC2AN" , 0x00111204, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO112SB0AN" , 0x00111205, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO112SB1AN" , 0x00111206, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO112SC1AN" , 0x00111207, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO112SC2AN" , 0x00111208, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO112RB0AN" , 0x00111209, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO112RB1AN" , 0x00111210, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO112RC1AN" , 0x00111211, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO112RC2AN" , 0x00111212, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO112VB0AN" , 0x00111213, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO112VB1AN" , 0x00111214, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO112VC1AN" , 0x00111215, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO112VC2AN" , 0x00111216, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO102ZB0AN" , 0x00110201, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO102ZB1AN" , 0x00110202, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO102ZC1AN" , 0x00110203, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO102ZC2AN" , 0x00110204, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO102LB0AN" , 0x00110205, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO102LB1AN" , 0x00110206, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO102LC1AN" , 0x00110207, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO102LC2AN" , 0x00110208, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO102SB0AN" , 0x00110209, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO102SB1AN" , 0x00110210, NUMICRO_BANKS_NANO(16*1024)}, +- {"NANO102SC1AN" , 0x00110211, NUMICRO_BANKS_NANO(32*1024)}, +- {"NANO102SC2AN" , 0x00110212, NUMICRO_BANKS_NANO(32*1024)}, +- +- /* NUC103/NUC105/NUC123 */ +- {"NUC123SC2AN" , 0x00012305, NUMICRO_BANKS_NUC100(36*1024)}, +- {"NUC123SD4AN" , 0x00012315, NUMICRO_BANKS_NUC100(68*1024)}, +- {"NUC123LC2AN" , 0x00012325, NUMICRO_BANKS_NUC100(36*1024)}, +- {"NUC103LC2AN" , 0x00010325, NUMICRO_BANKS_NUC100(36*1024)}, +- {"NUC105LC2AN" , 0x00010525, NUMICRO_BANKS_NUC100(36*1024)}, +- {"NUC123LD4AN" , 0x00012335, NUMICRO_BANKS_NUC100(68*1024)}, +- {"NUC103LD4AN" , 0x00010335, NUMICRO_BANKS_NUC100(68*1024)}, +- {"NUC105LD4AN" , 0x00010535, NUMICRO_BANKS_NUC100(68*1024)}, +- {"NUC123ZC2AN" , 0x00012345, NUMICRO_BANKS_NUC100(36*1024)}, +- {"NUC103ZC2AN" , 0x00010345, NUMICRO_BANKS_NUC100(36*1024)}, +- {"NUC105ZC2AN" , 0x00010545, NUMICRO_BANKS_NUC100(36*1024)}, +- {"NUC123ZD4AN" , 0x00012355, NUMICRO_BANKS_NUC100(68*1024)}, +- {"NUC103ZD4AN" , 0x00010355, NUMICRO_BANKS_NUC100(68*1024)}, +- {"NUC105ZD4AN" , 0x00010555, NUMICRO_BANKS_NUC100(68*1024)}, +- +- /* NUC200 */ +- {"NUC200LC2AN" , 0x00020007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC200LD2AN" , 0x00020004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC200LE3AN" , 0x00020000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC200SC1AN" , 0x00020035, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC200SD2AN" , 0x00020031, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC200SE3AN" , 0x00020027, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC200VE3AN" , 0x00020018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC220LC2AN" , 0x00022007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC220LD2AN" , 0x00022004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC220LE3AN" , 0x00022000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC220SC1AN" , 0x00022035, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC220SD2AN" , 0x00022031, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC220SE3AN" , 0x00022027, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC220VE3AN" , 0x00022018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC230LC2AN" , 0x00023007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC230LD2AN" , 0x00023004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC230LE3AN" , 0x00023000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC230SC1AN" , 0x00023035, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC230SD2AN" , 0x00023031, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC230SE3AN" , 0x00023027, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC230VE3AN" , 0x00023018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC240LC2AN" , 0x00024007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC240LD2AN" , 0x00024004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC240LE3AN" , 0x00024000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC240SC1AN" , 0x00024035, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC240SD2AN" , 0x00024031, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC240SE3AN" , 0x00024027, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC240VE3AN" , 0x00024018, NUMICRO_BANKS_NUC100(128*1024)}, +- +- /* NUC200 NUC2XXAE */ +- {"NUC230RC1AE" , 0x40013017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC200LC2AE" , 0x10020007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC200LD2AE" , 0x10020004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC200LE3AE" , 0x10020000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC200SC2AE" , 0x10020034, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC200SD2AE" , 0x10020031, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC200SE3AE" , 0x10020027, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC200VE3AE" , 0x10020018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC230LC2AE" , 0x10023007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC230LD2AE" , 0x10023004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC230LE3AE" , 0x10023000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC230SC2AE" , 0x10023034, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC230SD2AE" , 0x10023031, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC230SE3AE" , 0x10023027, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC230VE3AE" , 0x10023018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC240LC2AE" , 0x10024007, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC240LD2AE" , 0x10024004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC240LE3AE" , 0x10024000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC240SC2AE" , 0x10024034, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC240SD2AE" , 0x10024031, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC240SE3AE" , 0x10024027, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC240VE3AE" , 0x10024018, NUMICRO_BANKS_NUC100(128*1024)}, +- +- /* NUC100 Version D */ +- {"NUC100LC1DN" , 0x30010008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100LD1DN" , 0x30010005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LD2DN" , 0x30010004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RC1DN" , 0x30010017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC100RD1DN" , 0x30010014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RD2DN" , 0x30010013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LD3DN" , 0x30010003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100LE3DN" , 0x30010000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100RD3DN" , 0x30010012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100RE3DN" , 0x30010009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC100VD2DN" , 0x30010022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100VD3DN" , 0x30010021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC100VE3DN" , 0x30010018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120LC1DN" , 0x30012008, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120LD1DN" , 0x30012005, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LD2DN" , 0x30012004, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RC1DN" , 0x30012017, NUMICRO_BANKS_NUC100(32*1024)}, +- {"NUC120RD1DN" , 0x30012014, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RD2DN" , 0x30012013, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LD3DN" , 0x30012003, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120LE3DN" , 0x30012000, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120RD3DN" , 0x30012012, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120RE3DN" , 0x30012009, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC120VD2DN" , 0x30012022, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120VD3DN" , 0x30012021, NUMICRO_BANKS_NUC100(64*1024)}, +- {"NUC120VE3DN" , 0x30012018, NUMICRO_BANKS_NUC100(128*1024)}, +- {"NUC130RC1DN" , 0x30013017, NUMICRO_BANKS_NUC100(32*1024)}, +- +- {"UNKNOWN" , 0x00000000, NUMICRO_BANKS_NUC100(128*1024)}, ++ /* M051AN */ ++ {"M052LAN", 0x00005200, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M054LAN", 0x00005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M058LAN", 0x00005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M0516LAN", 0x00005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M052ZAN", 0x00005203, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M054ZAN", 0x00005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M058ZAN", 0x00005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M0516ZAN", 0x00005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ ++ /* M051BN */ ++ {"M052LBN", 0x10005200, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M054LBN", 0x10005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M058LBN", 0x10005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M0516LBN", 0x10005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M052ZBN", 0x10005203, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M054ZBN", 0x10005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M058ZBN", 0x10005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M0516ZBN", 0x10005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ ++ /* M051DN */ ++ {"M0516LDN", 0x20005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M0516ZDN", 0x20005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M052LDN", 0x20005200, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M052ZDN", 0x20005203, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M054LDN", 0x20005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M054ZDN", 0x20005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M058LDN", 0x20005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M058ZDN", 0x20005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ ++ /* M051DE */ ++ {"M0516LDE", 0x30005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M0516ZDE", 0x30005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M052LDE", 0x30005200, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M052ZDE", 0x30005203, NUMICRO_BANKS_GENERAL(8 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M054LDE", 0x30005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M054ZDE", 0x30005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M058LDE", 0x30005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"M058ZDE", 0x30005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ ++ /* M0518 */ ++ {"M0518LC2AE", 0x10051803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"M0518LD2AE", 0x10051800, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"M0518SC2AE", 0x10051813, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"M0518SD2AE", 0x10051810, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ ++ /* M0519 */ ++ {"M0519LD3AE", 0x00051902, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"M0519LE3AE", 0x00051900, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ {"M0519SD3AE", 0x00051922, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"M0519SE3AE", 0x00051920, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ {"M0519VE3AE", 0x00051930, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ ++ /* M058S */ ++ {"M058SFAN", 0x00005818, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"M058SLAN", 0x00005810, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"M058SSAN", 0x00005816, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"M058SZAN", 0x00005813, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ ++ /* MINI51AN */ ++ {"MINI51LAN", 0x00205100, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI51TAN", 0x00205104, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI51ZAN", 0x00205103, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI52LAN", 0x00205200, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI52TAN", 0x00205204, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI52ZAN", 0x00205203, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI54LAN", 0x00205400, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI54TAN", 0x00205404, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI54ZAN", 0x00205403, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ ++ /* MINI51DE */ ++ {"MINI51FDE", 0x20205105, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI51LDE", 0x20205100, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI51TDE", 0x20205104, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI51ZDE", 0x20205103, NUMICRO_BANKS_GENERAL(4 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI52FDE", 0x20205205, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI52LDE", 0x20205200, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI52TDE", 0x20205204, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI52ZDE", 0x20205203, NUMICRO_BANKS_GENERAL(8 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI54FDE", 0x20205405, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI54LDE", 0x20205400, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI54TDE", 0x20205404, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI54ZDE", 0x20205403, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ ++ /* MINI55 */ ++ {"MINI55LDE", 0x00505500, NUMICRO_BANKS_GENERAL(35 * 512, 0 * 1024, 2 * 1024, 8)}, ++ {"MINI55ZDE", 0x00505503, NUMICRO_BANKS_GENERAL(35 * 512, 0 * 1024, 2 * 1024, 8)}, ++ ++ /* MINI58 */ ++ {"MINI58FDE", 0x00A05805, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)}, ++ {"MINI58LDE", 0x00A05800, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)}, ++ {"MINI58TDE", 0x00A05804, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)}, ++ {"MINI58ZDE", 0x00A05803, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)}, ++ ++ /* NANO100AN */ ++ {"NANO100LC2AN", 0x00110025, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100LD2AN", 0x00110019, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100LD3AN", 0x00110018, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100SC2AN", 0x00110023, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100SD2AN", 0x00110016, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100SD3AN", 0x00110015, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100VD2AN", 0x00110013, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100VD3AN", 0x00110012, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100ZC2AN", 0x00110029, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100ZD2AN", 0x00110028, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100ZD3AN", 0x00110027, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120LC2AN", 0x00112025, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120LD2AN", 0x00112019, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120LD3AN", 0x00112018, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120SC2AN", 0x00112023, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120SD2AN", 0x00112016, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120SD3AN", 0x00112015, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120VD2AN", 0x00112013, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120VD3AN", 0x00112012, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120ZC2AN", 0x00112029, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120ZD2AN", 0x00112028, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120ZD3AN", 0x00112027, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NANO100BN */ ++ {"NANO100KC2BN", 0x00110040, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100KD2BN", 0x00110039, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100KD3BN", 0x00110038, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100KE3BN", 0x00110030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100LC2BN", 0x00110043, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100LD2BN", 0x0011003F, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100LD3BN", 0x0011003E, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100LE3BN", 0x00110036, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100ND2BN", 0x00110046, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100ND3BN", 0x00110045, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100NE3BN", 0x00110044, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100SC2BN", 0x00110042, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100SD2BN", 0x0011003D, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100SD3BN", 0x0011003C, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO100SE3BN", 0x00110034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110KC2BN", 0x00111040, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110KD2BN", 0x00111039, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110KD3BN", 0x00111038, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110KE3BN", 0x00111030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110RC2BN", 0x00111043, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110RD2BN", 0x00111044, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110RD3BN", 0x00111045, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110SC2BN", 0x00111042, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110SD2BN", 0x0011103D, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110SD3BN", 0x0011103C, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO110SE3BN", 0x00111034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120KC2BN", 0x00112040, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120KD2BN", 0x00112039, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120KD3BN", 0x00112038, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120KE3BN", 0x00112030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120LC2BN", 0x00112043, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120LD2BN", 0x0011203F, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120LD3BN", 0x0011203E, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120LE3BN", 0x00112036, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120SC2BN", 0x00112042, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120SD2BN", 0x0011203D, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120SD3BN", 0x0011203C, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO120SE3BN", 0x00112034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO130KC2BN", 0x00113040, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO130KD2BN", 0x00113039, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO130KD3BN", 0x00113038, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO130KE3BN", 0x00113030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO130SC2BN", 0x00113042, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO130SD2BN", 0x0011303D, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO130SD3BN", 0x0011303C, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO130SE3BN", 0x00113034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NANO103 */ ++ {"NANO103SD3AE", 0x00110301, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO103LD3AE", 0x00110304, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO103ZD3AE", 0x00110307, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NANO112AN */ ++ {"NANO102LB1AN", 0x00110206, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO102LC2AN", 0x00110208, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO102SC2AN", 0x00110212, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO102ZB1AN", 0x00110202, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO102ZC2AN", 0x00110204, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO112LB1AN", 0x00111202, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO112LC2AN", 0x00111204, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO112RB1AN", 0x00111210, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO112RC2AN", 0x00111212, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO112SB1AN", 0x00111206, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO112SC2AN", 0x00111208, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NANO112VC2AN", 0x00111216, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC029AN */ ++ {"NUC029LAN", 0x00295A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ {"NUC029TAN", 0x00295804, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)}, ++ ++ /* NUC029AE */ ++ {"NUC029FAE", 0x00295415, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)}, ++ ++ /* NUC100AN */ ++ {"NUC100LD3AN", 0x00010003, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100LE3AN", 0x00010000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC100RD3AN", 0x00010012, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100RE3AN", 0x00010009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC100VD2AN", 0x00010022, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100VD3AN", 0x00010021, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100VE3AN", 0x00100018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC120LD3AN", 0x00012003, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120LE3AN", 0x00120000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC120RD3AN", 0x00012012, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120RE3AN", 0x00012009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC120VD2AN", 0x00012022, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120VD3AN", 0x00012021, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120VE3AN", 0x00012018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC100BN */ ++ {"NUC100LC1BN", 0x10010008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100LD1BN", 0x10010005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100LD2BN", 0x10010004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100RC1BN", 0x10010017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100RD1BN", 0x10010014, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100RD2BN", 0x10010013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120LC1BN", 0x10012008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120LD1BN", 0x10012005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120LD2BN", 0x10012004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120RC1BN", 0x10012017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120RD1BN", 0x10012014, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120RD2BN", 0x10012013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC100CN */ ++ {"NUC130LC1CN", 0x20013008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC130LD2CN", 0x20013004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC130LE3CN", 0x20013000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC130RC1CN", 0x20013017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC130RD2CN", 0x20013013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC130RE3CN", 0x20013009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC130VE3CN", 0x20013018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC140LC1CN", 0x20014008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC140LD2CN", 0x20014004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC140LE3CN", 0x20014000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC140RC1CN", 0x20014017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC140RD2CN", 0x20014013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC140RE3CN", 0x20014009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC140VE3CN", 0x20014018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC100DN */ ++ {"NUC100LC1DN", 0x30010008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100LD1DN", 0x30010005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100LD2DN", 0x30010004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100LD3DN", 0x30010003, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100LE3DN", 0x30010000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC100RC1DN", 0x30010017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100RD1DN", 0x30010014, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100RD2DN", 0x30010013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100RD3DN", 0x30010012, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100RE3DN", 0x30010009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC100VD2DN", 0x30010022, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100VD3DN", 0x30010021, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC100VE3DN", 0x30010018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC120LC1DN", 0x30012008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120LD1DN", 0x30012005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120LD2DN", 0x30012004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120LD3DN", 0x30012003, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120LE3DN", 0x30012000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC120RC1DN", 0x30012035, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120RD1DN", 0x30012032, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120RD2DN", 0x30012031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120RD3DN", 0x30012030, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120RE3DN", 0x30012027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC120VD2DN", 0x30012022, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120VD3DN", 0x30012021, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC120VE3DN", 0x30012018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC121 */ ++ {"NUC121SC2AE", 0x00012105, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)}, ++ {"NUC121LC2AE", 0x00012125, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)}, ++ {"NUC121ZC2AE", 0x00012145, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)}, ++ {"NUC125SC2AE", 0x00012505, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)}, ++ {"NUC125LC2AE", 0x00012525, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)}, ++ {"NUC125ZC2AE", 0x00012545, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)}, ++ ++ /* NUC122 */ ++ {"NUC122LC1AN", 0x00012208, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC122LD2AN", 0x00012204, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC122SC1AN", 0x00012226, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC122SD2AN", 0x00012222, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC122ZC1AN", 0x00012235, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC122ZD2AN", 0x00012231, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC123AN */ ++ {"NUC123LC2AN1", 0x00012325, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123LD4AN0", 0x00012335, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123SC2AN1", 0x00012305, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123SD4AN0", 0x00012315, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123ZC2AN1", 0x00012345, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123ZD4AN0", 0x00012355, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC123AE */ ++ {"NUC123LC2AE1", 0x10012325, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123LD4AE0", 0x10012335, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123SC2AE1", 0x10012305, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123SD4AE0", 0x10012315, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123ZC2AE1", 0x10012345, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC123ZD4AE0", 0x10012355, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC131AE */ ++ {"NUC131LC2AE", 0x10013103, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC131LD2AE", 0x10013100, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC131SC2AE", 0x10013113, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC131SD2AE", 0x10013110, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC200/220AN */ ++ {"NUC200LC2AN", 0x00020007, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC200LD2AN", 0x00020004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC200LE3AN", 0x00020000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC200SC2AN", 0x00020034, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC200SD2AN", 0x00020031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC200SE3AN", 0x00020027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC200VE3AN", 0x00020018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC220LC2AN", 0x00022007, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC220LD2AN", 0x00022004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC220LE3AN", 0x00022000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC220SC2AN", 0x00022034, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC220SD2AN", 0x00022031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)}, ++ {"NUC220SE3AN", 0x00022027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"NUC220VE3AN", 0x00022018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC230/240AE */ ++ {"NUC230LC2AE", 0x10023007, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"NUC230LD2AE", 0x10023004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"NUC230LE3AE", 0x10023000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ {"NUC230SC2AE", 0x10023034, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"NUC230SD2AE", 0x10023031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"NUC230SE3AE", 0x10023027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ {"NUC230VE3AE", 0x10023018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ {"NUC240LC2AE", 0x10024007, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"NUC240LD2AE", 0x10024004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"NUC240LE3AE", 0x10024000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ {"NUC240SC2AE", 0x10024034, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"NUC240SD2AE", 0x10024031, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 8 * 1024, 8)}, ++ {"NUC240SE3AE", 0x10024027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ {"NUC240VE3AE", 0x10024018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, ++ ++ {"UNKNOWN", 0x00000000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 16 * 1024, 8)}, + }; + + /* Private bank information for NuMicro. */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0021-flash-support-Nuvoton-M541-NUC442-472-series.patch b/meta-oe/recipes-devtools/openocd/openocd/0021-flash-support-Nuvoton-M541-NUC442-472-series.patch new file mode 100644 index 000000000..42bf2cd95 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0021-flash-support-Nuvoton-M541-NUC442-472-series.patch @@ -0,0 +1,649 @@ +From d1b0cb2b774c1033a6ca8e531781df82baac40f7 Mon Sep 17 00:00:00 2001 +From: Zale Yu +Date: Sun, 6 Nov 2022 23:32:22 +0800 +Subject: [PATCH] flash: support Nuvoton M541 & NUC442/472 series + +This patch is picked from the flash part of OpenOCD-Nuvoton's commit +("flash: supported Nuvoton M4 series. jtag: Used HW reset instead of +auto reset. tcl: added a configuration file for Nuvoton M4 series.") [1] +to support flashing Nuvoton's Cortex-M4 chips: M541 & NUC442/472 series. + +The code comes from the commit basically. Jian-Hong Pan tweaked for the +compatibility with current OpenOCD. So, leave the author as Zale Yu. + +[1]: https://github.com/OpenNuvoton/OpenOCD-Nuvoton/commit/c2d5b8bfc705 + +Signed-off-by: Zale Yu +Signed-off-by: Jian-Hong Pan +Change-Id: I9dc69eccb851df14c1b0ce2f619d7b3da0aa92aa +Reviewed-on: https://review.openocd.org/c/openocd/+/7329 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/numicro.c | 334 ++++++++++++++++++++++++++++++---------- + 1 file changed, 253 insertions(+), 81 deletions(-) + +diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c +index bafad80ce..2bba7b746 100644 +--- a/src/flash/nor/numicro.c ++++ b/src/flash/nor/numicro.c +@@ -466,6 +466,65 @@ static const struct numicro_cpu_type numicro_parts[] = { + {"NUC240SE3AE", 0x10024027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, + {"NUC240VE3AE", 0x10024018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)}, + ++ /* M451 */ ++ {"M451LC3AE", 0x00945101, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451LD3AE", 0x00945100, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451LE6AE", 0x00845101, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451LG6AE", 0x00845100, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451MLC3AE", 0x00945001, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451MLD3AE", 0x00945000, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451MLE6AE", 0x00845001, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451MLG6AE", 0x00845000, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451MSC3AE", 0x00945011, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451MSD3AE", 0x00945010, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451RC3AE", 0x00945121, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451RD3AE", 0x00945120, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451RE6AE", 0x00845121, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451RG6AE", 0x00845120, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451VE6AE", 0x00845131, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M451VG6AE", 0x00845130, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M452LC3AE", 0x00945201, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M452LD3AE", 0x00945200, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M452LE6AE", 0x00845201, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M452LG6AE", 0x00845200, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M452RD3AE", 0x00945220, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M452RE6AE", 0x00845221, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M452RG6AE", 0x00845220, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453LC3AE", 0x00945301, NUMICRO_BANKS_GENERAL(40 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453LD3AE", 0x00945300, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453LE6AE", 0x00845301, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453LG6AE", 0x00845300, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453RD3AE", 0x00945320, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453RE6AE", 0x00845321, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453RG6AE", 0x00845320, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453VD3AE", 0x00945330, NUMICRO_BANKS_GENERAL(72 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453VE6AE", 0x00845331, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M453VG6AE", 0x00845330, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M4TKVG6AE", 0x00845430, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M4TKVE6AE", 0x00845431, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M4TKRG6AE", 0x00845420, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M4TKRE6AE", 0x00845421, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M4TKLG6AE", 0x00845400, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ {"M4TKLE6AE", 0x00845401, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)}, ++ ++ /* NUC442_472 */ ++ {"NUC442JG8AE", 0x00044203, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC442JI8AE", 0x00044201, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC442KG8AE", 0x00044206, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC442KI8AE", 0x00044204, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC442RG8AE", 0x00044212, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC442RI8AE", 0x00044210, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC442VG8AE", 0x00044209, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC442VI8AE", 0x00044207, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC472HG8AE", 0x00047203, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC472HI8AE", 0x00047201, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC472JG8AE", 0x00047206, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC472JI8AE", 0x00047204, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC472KG8AE", 0x00047209, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC472KI8AE", 0x00047207, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC472VG8AE", 0x00047212, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ {"NUC472VI8AE", 0x00047210, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)}, ++ + {"UNKNOWN", 0x00000000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 16 * 1024, 8)}, + }; + +@@ -476,32 +535,53 @@ struct numicro_flash_bank { + const struct numicro_cpu_type *cpu; + }; + ++/* Private variables */ ++uint32_t m_page_size = NUMICRO_PAGESIZE; ++uint32_t m_address_bias_offset; ++ + /* Private methods */ ++static int numicro_get_arm_arch(struct target *target) ++{ ++ struct armv7m_common *armv7m = target_to_armv7m(target); ++ ++ if (armv7m->arm.arch != ARM_ARCH_V6M) { ++ LOG_DEBUG("NuMicro arm architecture: armv7m\n"); ++ m_page_size = NUMICRO_PAGESIZE * 4; ++ m_address_bias_offset = 0x10000000; ++ } else { ++ LOG_DEBUG("NuMicro arm architecture: armv6m\n"); ++ m_page_size = NUMICRO_PAGESIZE; ++ m_address_bias_offset = 0x0; ++ } ++ ++ return ERROR_OK; ++} ++ + static int numicro_reg_unlock(struct target *target) + { + uint32_t is_protected; + int retval = ERROR_OK; + + /* Check to see if NUC is register unlocked or not */ +- retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected); ++ retval = target_read_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, &is_protected); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("protected = 0x%08" PRIx32 "", is_protected); + if (is_protected == 0) { /* means protected - so unlock it */ + /* unlock flash registers */ +- retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY1); ++ retval = target_write_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, REG_KEY1); + if (retval != ERROR_OK) + return retval; +- retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY2); ++ retval = target_write_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, REG_KEY2); + if (retval != ERROR_OK) + return retval; +- retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY3); ++ retval = target_write_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, REG_KEY3); + if (retval != ERROR_OK) + return retval; + } + /* Check that unlock worked */ +- retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected); ++ retval = target_read_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, &is_protected); + if (retval != ERROR_OK) + return retval; + +@@ -529,27 +609,27 @@ static int numicro_init_isp(struct target *target) + return retval; + + /* Enable ISP/SRAM/TICK Clock */ +- retval = target_read_u32(target, NUMICRO_SYSCLK_AHBCLK, ®_stat); ++ retval = target_read_u32(target, NUMICRO_SYSCLK_AHBCLK - m_address_bias_offset, ®_stat); + if (retval != ERROR_OK) + return retval; + + reg_stat |= AHBCLK_ISP_EN | AHBCLK_SRAM_EN | AHBCLK_TICK_EN; +- retval = target_write_u32(target, NUMICRO_SYSCLK_AHBCLK, reg_stat); ++ retval = target_write_u32(target, NUMICRO_SYSCLK_AHBCLK - m_address_bias_offset, reg_stat); + if (retval != ERROR_OK) + return retval; + + /* Enable ISP */ +- retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, ®_stat); ++ retval = target_read_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, ®_stat); + if (retval != ERROR_OK) + return retval; + + reg_stat |= ISPCON_ISPFF | ISPCON_LDUEN | ISPCON_APUEN | ISPCON_CFGUEN | ISPCON_ISPEN; +- retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, reg_stat); ++ retval = target_write_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, reg_stat); + if (retval != ERROR_OK) + return retval; + + /* Write one to undocumented flash control register */ +- retval = target_write_u32(target, NUMICRO_FLASH_CHEAT, 1); ++ retval = target_write_u32(target, NUMICRO_FLASH_CHEAT - m_address_bias_offset, 1); + if (retval != ERROR_OK) + return retval; + +@@ -561,29 +641,28 @@ static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t ad + uint32_t timeout, status; + int retval = ERROR_OK; + +- retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, cmd); ++ retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD - m_address_bias_offset, cmd); + if (retval != ERROR_OK) + return retval; + +- retval = target_write_u32(target, NUMICRO_FLASH_ISPDAT, wdata); ++ retval = target_write_u32(target, NUMICRO_FLASH_ISPDAT - m_address_bias_offset, wdata); + if (retval != ERROR_OK) + return retval; + +- retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, addr); ++ retval = target_write_u32(target, NUMICRO_FLASH_ISPADR - m_address_bias_offset, addr); + if (retval != ERROR_OK) + return retval; + +- retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); ++ retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG - m_address_bias_offset, ISPTRG_ISPGO); + if (retval != ERROR_OK) + return retval; + + /* Wait for busy to clear - check the GO flag */ + timeout = 100; + for (;;) { +- retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status); ++ retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG - m_address_bias_offset, &status); + if (retval != ERROR_OK) + return retval; +- LOG_DEBUG("status: 0x%" PRIx32 "", status); + if ((status & (ISPTRG_ISPGO)) == 0) + break; + if (timeout-- <= 0) { +@@ -593,79 +672,138 @@ static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t ad + busy_sleep(1); /* can use busy sleep for short times. */ + } + +- retval = target_read_u32(target, NUMICRO_FLASH_ISPDAT, rdata); ++ retval = target_read_u32(target, NUMICRO_FLASH_ISPDAT - m_address_bias_offset, rdata); + if (retval != ERROR_OK) + return retval; + + return ERROR_OK; + } + +- + /* NuMicro Program-LongWord Microcodes */ + static const uint8_t numicro_flash_write_code[] = { +- /* Params: +- * r0 - workarea buffer / result +- * r1 - target address +- * r2 - wordcount +- * Clobbered: +- * r4 - tmp +- * r5 - tmp +- * r6 - tmp +- * r7 - tmp +- */ +- +- /* .L1: */ +- /* for(register uint32_t i=0;itarget; +- uint32_t buffer_size = 1024; /* Default minimum value */ ++ uint32_t buffer_size = 1024; /* Default minimum value */ + struct working_area *write_algorithm; + struct working_area *source; + uint32_t address = bank->base + offset; +@@ -693,18 +831,34 @@ static int numicro_writeblock(struct flash_bank *bank, const uint8_t *buffer, + LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset); + return ERROR_FLASH_DST_BREAKS_ALIGNMENT; + } ++ /* Difference between M0 and M4 */ ++ if (m_page_size == NUMICRO_PAGESIZE) { ++ /* allocate working area with flash programming code */ ++ if (target_alloc_working_area(target, sizeof(numicro_flash_write_code), ++ &write_algorithm) != ERROR_OK) { ++ LOG_WARNING("no working area available, can't do block memory writes"); ++ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; ++ } + +- /* allocate working area with flash programming code */ +- if (target_alloc_working_area(target, sizeof(numicro_flash_write_code), ++ retval = target_write_buffer(target, write_algorithm->address, ++ sizeof(numicro_flash_write_code), numicro_flash_write_code); ++ if (retval != ERROR_OK) ++ return retval; ++ } else { /* for M4 */ ++ /* allocate working area with flash programming code */ ++ if (target_alloc_working_area(target, sizeof(numicro_m4_flash_write_code), + &write_algorithm) != ERROR_OK) { +- LOG_WARNING("no working area available, can't do block memory writes"); +- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; +- } ++ LOG_WARNING("no working area available, can't do block memory writes"); ++ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; ++ } + +- retval = target_write_buffer(target, write_algorithm->address, +- sizeof(numicro_flash_write_code), numicro_flash_write_code); +- if (retval != ERROR_OK) +- return retval; ++ retval = target_write_buffer(target, write_algorithm->address, ++ sizeof(numicro_m4_flash_write_code), numicro_m4_flash_write_code); ++ if (retval != ERROR_OK) ++ return retval; ++ ++ buffer_size = m_page_size; ++ } + + /* memory buffer */ + while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) { +@@ -775,13 +929,14 @@ static int numicro_protect_check(struct flash_bank *bank) + + LOG_INFO("Nuvoton NuMicro: Flash Lock Check..."); + ++ numicro_get_arm_arch(target); + retval = numicro_init_isp(target); + if (retval != ERROR_OK) + return retval; + + /* Read CONFIG0,CONFIG1 */ +- numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG0, 0 , &config[0]); +- numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG1, 0 , &config[1]); ++ numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG0 - m_address_bias_offset, 0, &config[0]); ++ numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG1 - m_address_bias_offset, 0, &config[1]); + + LOG_DEBUG("CONFIG0: 0x%" PRIx32 ",CONFIG1: 0x%" PRIx32 "", config[0], config[1]); + +@@ -821,31 +976,34 @@ static int numicro_erase(struct flash_bank *bank, unsigned int first, + + LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%u to %u)", first, last); + ++ numicro_get_arm_arch(target); + retval = numicro_init_isp(target); + if (retval != ERROR_OK) + return retval; + +- retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_ERASE); ++ retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD - m_address_bias_offset, ISPCMD_ERASE); + if (retval != ERROR_OK) + return retval; + + for (unsigned int i = first; i <= last; i++) { +- LOG_DEBUG("erasing sector %u at address " TARGET_ADDR_FMT, i, +- bank->base + bank->sectors[i].offset); +- retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + bank->sectors[i].offset); ++ LOG_DEBUG("erasing sector %u at address " TARGET_ADDR_FMT, i, bank->base + bank->sectors[i].offset); ++ retval = target_write_u32(target, ++ NUMICRO_FLASH_ISPADR - m_address_bias_offset, ++ bank->base + bank->sectors[i].offset); + if (retval != ERROR_OK) + return retval; +- retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); /* This is the only bit available */ ++ retval = target_write_u32(target, ++ NUMICRO_FLASH_ISPTRG - m_address_bias_offset, ++ ISPTRG_ISPGO); /* This is the only bit available */ + if (retval != ERROR_OK) + return retval; + + /* wait for busy to clear - check the GO flag */ + timeout = 100; + for (;;) { +- retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status); ++ retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG - m_address_bias_offset, &status); + if (retval != ERROR_OK) + return retval; +- LOG_DEBUG("status: 0x%" PRIx32 "", status); + if (status == 0) + break; + if (timeout-- <= 0) { +@@ -856,13 +1014,13 @@ static int numicro_erase(struct flash_bank *bank, unsigned int first, + } + + /* check for failure */ +- retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status); ++ retval = target_read_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, &status); + if (retval != ERROR_OK) + return retval; + if ((status & ISPCON_ISPFF) != 0) { + LOG_DEBUG("failure: 0x%" PRIx32 "", status); + /* if bit is set, then must write to it to clear it. */ +- retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF)); ++ retval = target_write_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, (status | ISPCON_ISPFF)); + if (retval != ERROR_OK) + return retval; + } +@@ -889,11 +1047,12 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer, + + LOG_INFO("Nuvoton NuMicro: Flash Write ..."); + ++ numicro_get_arm_arch(target); + retval = numicro_init_isp(target); + if (retval != ERROR_OK) + return retval; + +- retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_WRITE); ++ retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD - m_address_bias_offset, ISPCMD_WRITE); + if (retval != ERROR_OK) + return retval; + +@@ -913,26 +1072,34 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer, + + /* program command */ + for (uint32_t i = 0; i < count; i += 4) { ++ /* write 4 bytes each time with 0xff padding to avoid unaligned case */ ++ uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff}; ++ memcpy(padding, buffer + i, MIN(4, count - i)); + +- LOG_DEBUG("write longword @ %08" PRIX32, offset + i); +- +- retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + offset + i); ++ retval = target_write_u32(target, ++ NUMICRO_FLASH_ISPADR - m_address_bias_offset, ++ bank->base + offset + i); + if (retval != ERROR_OK) + return retval; +- retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, buffer + i); ++ retval = target_write_memory(target, ++ NUMICRO_FLASH_ISPDAT - m_address_bias_offset, ++ 4, 1, padding); + if (retval != ERROR_OK) + return retval; +- retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); ++ retval = target_write_u32(target, ++ NUMICRO_FLASH_ISPTRG - m_address_bias_offset, ++ ISPTRG_ISPGO); + if (retval != ERROR_OK) + return retval; + + /* wait for busy to clear - check the GO flag */ + timeout = 100; + for (;;) { +- retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status); ++ retval = target_read_u32(target, ++ NUMICRO_FLASH_ISPTRG - m_address_bias_offset, ++ &status); + if (retval != ERROR_OK) + return retval; +- LOG_DEBUG("status: 0x%" PRIx32 "", status); + if (status == 0) + break; + if (timeout-- <= 0) { +@@ -946,13 +1113,15 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer, + } + + /* check for failure */ +- retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status); ++ retval = target_read_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, &status); + if (retval != ERROR_OK) + return retval; + if ((status & ISPCON_ISPFF) != 0) { + LOG_DEBUG("failure: 0x%" PRIx32 "", status); + /* if bit is set, then must write to it to clear it. */ +- retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF)); ++ retval = target_write_u32(target, ++ NUMICRO_FLASH_ISPCON - m_address_bias_offset, ++ (status | ISPCON_ISPFF)); + if (retval != ERROR_OK) + return retval; + } else { +@@ -970,8 +1139,9 @@ static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_ + uint32_t part_id; + int retval = ERROR_OK; + ++ numicro_get_arm_arch(target); + /* Read NuMicro PartID */ +- retval = target_read_u32(target, NUMICRO_SYS_BASE, &part_id); ++ retval = target_read_u32(target, NUMICRO_SYS_BASE - m_address_bias_offset, &part_id); + if (retval != ERROR_OK) { + LOG_WARNING("NuMicro flash driver: Failed to Get PartID\n"); + return ERROR_FLASH_OPERATION_FAILED; +@@ -1023,7 +1193,7 @@ static int numicro_probe(struct flash_bank *bank) + return ERROR_FLASH_OPERATION_FAILED; + } + +- num_pages = flash_size / NUMICRO_PAGESIZE; ++ num_pages = flash_size / m_page_size; + + bank->num_sectors = num_pages; + bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); +@@ -1031,10 +1201,10 @@ static int numicro_probe(struct flash_bank *bank) + + for (int i = 0; i < num_pages; i++) { + bank->sectors[i].offset = offset; +- bank->sectors[i].size = NUMICRO_PAGESIZE; ++ bank->sectors[i].size = m_page_size; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 0; +- offset += NUMICRO_PAGESIZE; ++ offset += m_page_size; + } + + struct numicro_flash_bank *numicro_info = bank->driver_priv; +@@ -1073,7 +1243,6 @@ FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command) + bank->write_start_alignment = bank->write_end_alignment = 4; + + return ERROR_OK; +- + } + + COMMAND_HANDLER(numicro_handle_read_isp_command) +@@ -1089,6 +1258,7 @@ COMMAND_HANDLER(numicro_handle_read_isp_command) + + struct target *target = get_current_target(CMD_CTX); + ++ numicro_get_arm_arch(target); + retval = numicro_init_isp(target); + if (retval != ERROR_OK) + return retval; +@@ -1116,6 +1286,7 @@ COMMAND_HANDLER(numicro_handle_write_isp_command) + + struct target *target = get_current_target(CMD_CTX); + ++ numicro_get_arm_arch(target); + retval = numicro_init_isp(target); + if (retval != ERROR_OK) + return retval; +@@ -1138,6 +1309,7 @@ COMMAND_HANDLER(numicro_handle_chip_erase_command) + + struct target *target = get_current_target(CMD_CTX); + ++ numicro_get_arm_arch(target); + retval = numicro_init_isp(target); + if (retval != ERROR_OK) + return retval; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0022-tcl-add-a-configuration-file-for-Nuvoton-M541-NUC442.patch b/meta-oe/recipes-devtools/openocd/openocd/0022-tcl-add-a-configuration-file-for-Nuvoton-M541-NUC442.patch new file mode 100644 index 000000000..27bd959ad --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0022-tcl-add-a-configuration-file-for-Nuvoton-M541-NUC442.patch @@ -0,0 +1,101 @@ +From 21b14028ad7565f4916ae05a6c28b465eceb9150 Mon Sep 17 00:00:00 2001 +From: Zale Yu +Date: Fri, 4 Nov 2022 23:07:29 +0800 +Subject: [PATCH] tcl: add a configuration file for Nuvoton M541 & NUC442/472 + series + +This patch is picked from the tcl part of OpenOCD-Nuvoton's commit +("flash: supported Nuvoton M4 series. jtag: Used HW reset instead of +auto reset. tcl: added a configuration file for Nuvoton M4 series.") [1] +to support the communication with Nuvoton's Cortex-M4 chips: M541 & +NUC442/472 series. + +This patch has been tested with Nuvoton's NuTiny-SDK-NUC472 development +board [2]. + +The code comes from the commit basically. Jian-Hong Pan tweaked for the +compatibility with current OpenOCD. So, leave the author as Zale Yu. + +[1]: https://github.com/OpenNuvoton/OpenOCD-Nuvoton/commit/c2d5b8bfc705 +[2]: https://www.nuvoton.com/export/resource-files/UM_NuTiny-SDK- + NUC472_EN_Rev1.02.pdf + +Signed-off-by: Zale Yu +Signed-off-by: Jian-Hong Pan +Change-Id: I27ac58dd1c98a76e791a4f1117c31060cf5522e8 +Reviewed-on: https://review.openocd.org/c/openocd/+/7330 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + tcl/target/numicro_m4.cfg | 62 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 62 insertions(+) + create mode 100644 tcl/target/numicro_m4.cfg + +diff --git a/tcl/target/numicro_m4.cfg b/tcl/target/numicro_m4.cfg +new file mode 100644 +index 000000000..1302515d3 +--- /dev/null ++++ b/tcl/target/numicro_m4.cfg +@@ -0,0 +1,62 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++# script for Nuvoton MuMicro Cortex-M4 Series ++ ++source [find target/swj-dp.tcl] ++ ++# Set Chipname ++if { [info exists CHIPNAME] } { ++ set _CHIPNAME $CHIPNAME ++} else { ++ set _CHIPNAME NuMicro ++} ++ ++# SWD DP-ID Nuvoton NuMicro Cortex-M4 has SWD Transport only. ++if { [info exists CPUDAPID] } { ++ set _CPUDAPID $CPUDAPID ++} else { ++ set _CPUDAPID 0x2BA01477 ++} ++ ++# Work-area is a space in RAM used for flash programming ++# By default use 16kB ++if { [info exists WORKAREASIZE] } { ++ set _WORKAREASIZE $WORKAREASIZE ++} else { ++ set _WORKAREASIZE 0x4000 ++} ++ ++ ++# Debug Adapter Target Settings ++swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID ++dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu ++set _TARGETNAME $_CHIPNAME.cpu ++target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap ++ ++$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 ++ ++# flash bank numicro 0 0 ++#set _FLASHNAME $_CHIPNAME.flash ++#flash bank $_FLASHNAME numicro 0 $_FLASHSIZE 0 0 $_TARGETNAME ++# flash size will be probed ++set _FLASHNAME $_CHIPNAME.flash_aprom ++flash bank $_FLASHNAME numicro 0x00000000 0 0 0 $_TARGETNAME ++set _FLASHNAME $_CHIPNAME.flash_data ++flash bank $_FLASHNAME numicro 0x0001F000 0 0 0 $_TARGETNAME ++set _FLASHNAME $_CHIPNAME.flash_ldrom ++flash bank $_FLASHNAME numicro 0x00100000 0 0 0 $_TARGETNAME ++set _FLASHNAME $_CHIPNAME.flash_config ++flash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME ++ ++# set default SWCLK frequency ++adapter speed 1000 ++ ++# set default srst setting "none" ++reset_config none ++ ++# HLA doesn't have cortex_m commands ++if {![using_hla]} { ++ # if srst is not fitted use SYSRESETREQ to ++ # perform a soft reset ++ cortex_m reset_config sysresetreq ++} diff --git a/meta-oe/recipes-devtools/openocd/openocd/0023-flash-nor-contrib-loaders-move-numicro-M4-write-asse.patch b/meta-oe/recipes-devtools/openocd/openocd/0023-flash-nor-contrib-loaders-move-numicro-M4-write-asse.patch new file mode 100644 index 000000000..e36244f62 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0023-flash-nor-contrib-loaders-move-numicro-M4-write-asse.patch @@ -0,0 +1,216 @@ +From 63336f4aaf672899db78de4ce6781c9451851472 Mon Sep 17 00:00:00 2001 +From: Jian-Hong Pan +Date: Thu, 10 Nov 2022 00:14:10 +0800 +Subject: [PATCH] flash/nor, contrib/loaders: move numicro M4 write assembly to + contrib/loaders + +Simply move numicro M4 flash write assembly to contrib/loaders. Also, +add corresponding Makefile and generated numicro_m4.inc. + +Signed-off-by: Jian-Hong Pan +Change-Id: I22b8be0a245857335b11bd0b538db415fc34748d +Reviewed-on: https://review.openocd.org/c/openocd/+/7343 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + contrib/loaders/flash/numicro_m4/Makefile | 31 ++++++++ + contrib/loaders/flash/numicro_m4/numicro_m4.S | 70 +++++++++++++++++++ + .../loaders/flash/numicro_m4/numicro_m4.inc | 5 ++ + src/flash/nor/numicro.c | 57 +-------------- + 4 files changed, 107 insertions(+), 56 deletions(-) + create mode 100644 contrib/loaders/flash/numicro_m4/Makefile + create mode 100644 contrib/loaders/flash/numicro_m4/numicro_m4.S + create mode 100644 contrib/loaders/flash/numicro_m4/numicro_m4.inc + +diff --git a/contrib/loaders/flash/numicro_m4/Makefile b/contrib/loaders/flash/numicro_m4/Makefile +new file mode 100644 +index 000000000..0f9c507cd +--- /dev/null ++++ b/contrib/loaders/flash/numicro_m4/Makefile +@@ -0,0 +1,31 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++BIN2C = ../../../../src/helper/bin2char.sh ++ ++CROSS_COMPILE ?= arm-none-eabi- ++ ++CC=$(CROSS_COMPILE)gcc ++OBJCOPY=$(CROSS_COMPILE)objcopy ++OBJDUMP=$(CROSS_COMPILE)objdump ++ ++ ++AFLAGS = -static -nostartfiles -mlittle-endian -mcpu=cortex-m4 -Wa,-EL ++ ++all: numicro_m4.inc ++ ++.PHONY: clean ++ ++%.elf: %.S ++ $(CC) $(AFLAGS) $< -o $@ ++ ++%.lst: %.elf ++ $(OBJDUMP) -S $< > $@ ++ ++%.bin: %.elf ++ $(OBJCOPY) -Obinary $< $@ ++ ++%.inc: %.bin ++ $(BIN2C) < $< > $@ ++ ++clean: ++ -rm -f *.elf *.lst *.bin *.inc +diff --git a/contrib/loaders/flash/numicro_m4/numicro_m4.S b/contrib/loaders/flash/numicro_m4/numicro_m4.S +new file mode 100644 +index 000000000..6c59cca57 +--- /dev/null ++++ b/contrib/loaders/flash/numicro_m4/numicro_m4.S +@@ -0,0 +1,70 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++/*************************************************************************** ++ * Copyright (C) 2017 Zale Yu * ++ * CYYU@nuvoton.com * ++ * * ++ * Copyright (C) 2022 Jian-Hong Pan * ++ * chienhung.pan@gmail.com * ++ ***************************************************************************/ ++ ++ .text ++ .cpu cortex-m4 ++ .thumb ++ ++ /* Params: ++ * r0 - workarea buffer / result ++ * r1 - target address ++ * r2 - wordcount ++ * Clobbered: ++ * r4 - tmp ++ * r5 - tmp ++ * r6 - tmp ++ * r7 - tmp ++ */ ++ ++.L1: ++ /* for(register uint32_t i=0;i +Date: Sun, 13 Nov 2022 12:43:14 +0800 +Subject: [PATCH] flash/nor, contrib/loaders: move numicro M0 write assembly to + contrib/loaders + +Simply move numicro M0 flash write assembly to contrib/loaders. Also, +modify corresponding Makefile and generated numicro_m0.inc. + +To make the path more general, this patch rename the path +"contrib/loaders/flash/numicro_m4" to "contrib/loaders/flash/numicro" as +well. + +Signed-off-by: Jian-Hong Pan +Change-Id: I9adea24c2b3c97319a9b015cf50257f3d131dc26 +Reviewed-on: https://review.openocd.org/c/openocd/+/7346 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + .../flash/{numicro_m4 => numicro}/Makefile | 4 +- + contrib/loaders/flash/numicro/numicro_m0.S | 73 +++++++++++++++++++ + contrib/loaders/flash/numicro/numicro_m0.inc | 5 ++ + .../{numicro_m4 => numicro}/numicro_m4.S | 0 + .../{numicro_m4 => numicro}/numicro_m4.inc | 0 + src/flash/nor/numicro.c | 59 +-------------- + 6 files changed, 82 insertions(+), 59 deletions(-) + rename contrib/loaders/flash/{numicro_m4 => numicro}/Makefile (82%) + create mode 100644 contrib/loaders/flash/numicro/numicro_m0.S + create mode 100644 contrib/loaders/flash/numicro/numicro_m0.inc + rename contrib/loaders/flash/{numicro_m4 => numicro}/numicro_m4.S (100%) + rename contrib/loaders/flash/{numicro_m4 => numicro}/numicro_m4.inc (100%) + +diff --git a/contrib/loaders/flash/numicro_m4/Makefile b/contrib/loaders/flash/numicro/Makefile +similarity index 82% +rename from contrib/loaders/flash/numicro_m4/Makefile +rename to contrib/loaders/flash/numicro/Makefile +index 0f9c507cd..e4f44417c 100644 +--- a/contrib/loaders/flash/numicro_m4/Makefile ++++ b/contrib/loaders/flash/numicro/Makefile +@@ -9,9 +9,9 @@ OBJCOPY=$(CROSS_COMPILE)objcopy + OBJDUMP=$(CROSS_COMPILE)objdump + + +-AFLAGS = -static -nostartfiles -mlittle-endian -mcpu=cortex-m4 -Wa,-EL ++AFLAGS = -static -nostartfiles -mlittle-endian -Wa,-EL + +-all: numicro_m4.inc ++all: numicro_m0.inc numicro_m4.inc + + .PHONY: clean + +diff --git a/contrib/loaders/flash/numicro/numicro_m0.S b/contrib/loaders/flash/numicro/numicro_m0.S +new file mode 100644 +index 000000000..37d435532 +--- /dev/null ++++ b/contrib/loaders/flash/numicro/numicro_m0.S +@@ -0,0 +1,73 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++/*************************************************************************** ++ * Copyright (C) 2015 Nemui Trinomius * ++ * nemuisan_kawausogasuki@live.jp * ++ * * ++ * Copyright (C) 2017 Zale Yu * ++ * CYYU@nuvoton.com * ++ * * ++ * Copyright (C) 2022 Jian-Hong Pan * ++ * chienhung.pan@gmail.com * ++ ***************************************************************************/ ++ ++ .text ++ .cpu cortex-m0 ++ .thumb ++ ++ /* Params: ++ * r0 - workarea buffer / result ++ * r1 - target address ++ * r2 - wordcount ++ * Clobbered: ++ * r4 - tmp ++ * r5 - tmp ++ * r6 - tmp ++ * r7 - tmp ++ */ ++ ++.L1: ++ /* for(register uint32_t i=0;i +Date: Sat, 22 Oct 2022 18:12:16 +0200 +Subject: [PATCH] doc: usb_adapters: add container for lsusb dump of adapters + +When extending an existing adapter driver, developer has to +carefully avoid to break backward compatibility. +But not all developers have access to many adapters for testing. + +Prepare a folder aimed at containing 'lsusb -v' dumps of adapters +to be used as reference. +Add documentation and a simple dump script. + +Change-Id: Ia3a9132d65ec8869734721f9605cebcebcf33608 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7296 +Tested-by: jenkins +--- + doc/usb_adapters/dump.sh | 24 +++++++++++++++++++++ + doc/usb_adapters/readme.txt | 43 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 67 insertions(+) + create mode 100755 doc/usb_adapters/dump.sh + create mode 100644 doc/usb_adapters/readme.txt + +diff --git a/doc/usb_adapters/dump.sh b/doc/usb_adapters/dump.sh +new file mode 100755 +index 000000000..1ecfb40f0 +--- /dev/null ++++ b/doc/usb_adapters/dump.sh +@@ -0,0 +1,24 @@ ++#!/bin/sh ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++devs=$(lsusb -d $1:$2 | wc -l) ++case "$devs" in ++ 0 ) ++ echo "Error: USB device $1:$2 not found" > /dev/stderr ++ exit 1 ++ ;; ++ 1 ) ++ echo "Dumping $(lsusb -d $1:$2)" > /dev/stderr ++ ;; ++ * ) ++ echo "Error: Multiple matches for 'lsusb -d $1:$2'" > /dev/stderr ++ exit 1 ++ ;; ++esac ++ ++# break SPDX tag to hide it to checkpatch ++echo '# SPDX-''License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later' ++echo '' ++echo '# Optional comment' ++ ++lsusb -v -d $1:$2 | sed 's/ *$//' +diff --git a/doc/usb_adapters/readme.txt b/doc/usb_adapters/readme.txt +new file mode 100644 +index 000000000..1d995e99f +--- /dev/null ++++ b/doc/usb_adapters/readme.txt +@@ -0,0 +1,43 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++This folder contains a collection of dumps of USB descriptors, obtained through ++Linux lsusb command, of several USB adapters supported by OpenOCD. ++This collection should help maintaining adapter drivers even if the developer ++doesn't have access to all the devices supported by the driver. ++ ++To add a new file, run: ++ ++ ./doc/usb_adapters/dump.sh ${vid} ${pid} \ ++ > doc/usb_adapters/${driver}/${vid}_${pid}_${short_description}.txt ++ ++eventually edit the file to add some extra comment, then submit the file to ++OpenOCD gerrit, as explained in HACKING. ++ ++The dumps are organized in subfolders corresponding to OpenOCD drivers: ++- cmsis_dap; ++- ft232r; ++- ftdi; ++- icdi; ++- jlink; ++- kitprog; ++- nulink; ++- stlink; ++- xds110. ++ ++The script above assumes the user has granted access permissions to the USB ++device file in ++ /dev/bus/usb// ++This is usually the case when the device is listed in ++ contrib/60-openocd.rules ++and this udev rules file is properly installed in the host machine. ++If the user has no proper access permissions, the script has to be run as ++root or through 'sudo'. ++ ++Old versions of 'lsusb -v' dump cryptic errors like: ++ can't get device qualifier: Resource temporarily unavailable ++ can't get debug descriptor: Resource temporarily unavailable ++when some optional descriptor is not present. ++This is fixed in usbutils v014. ++If you get such messages simply ignore them. They are printed on stderr, so ++will not be included in the generated file as the redirection '>' does only ++redirects stdout. diff --git a/meta-oe/recipes-devtools/openocd/openocd/0026-doc-usb_adapters-add-lsusb-dump-of-few-adapters.patch b/meta-oe/recipes-devtools/openocd/openocd/0026-doc-usb_adapters-add-lsusb-dump-of-few-adapters.patch new file mode 100644 index 000000000..5c99855a7 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0026-doc-usb_adapters-add-lsusb-dump-of-few-adapters.patch @@ -0,0 +1,2773 @@ +From e0059dfffae4f8a55c39e25d0e8b2285559db65c Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sat, 22 Oct 2022 18:16:59 +0200 +Subject: [PATCH] doc: usb_adapters: add lsusb dump of few adapters + +Real dumps from adapters I have access to. +Serial numbers have been manually edited but are still consistent. + +Change-Id: Iee2d16e09615746e29588f91fdfb77eb9fad4daa +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7297 +Tested-by: jenkins +--- + .../cmsis_dap/0d28_0204_nxp_daplink.txt | 175 +++++++++++ + .../cmsis_dap/c251_2722_keil_ulink2.txt | 72 +++++ + doc/usb_adapters/ft232r/0403_6001_ft232r.txt | 64 ++++ + doc/usb_adapters/ftdi/0403_6010_ft2232h.txt | 103 +++++++ + .../ftdi/0403_cff8_amontec_jtagkey2.txt | 104 +++++++ + .../ftdi/09fb_6001_altera_blaster.txt | 64 ++++ + doc/usb_adapters/icdi/1cbe_00fd_ti_icdi.txt | 156 ++++++++++ + .../1366_0101_segger_jlink_plus_10_1.txt | 71 +++++ + .../nulink/0416_511d_nuvoton_nulink.txt | 142 +++++++++ + .../nulink/0416_5200_nuvoton_nulink.txt | 211 +++++++++++++ + .../stlink/0483_3744_stlinkv1.txt | 62 ++++ + .../stlink/0483_3748_stlinkv2.txt | 72 +++++ + .../stlink/0483_374b_stlinkv2.txt | 173 +++++++++++ + .../stlink/0483_374d_stlinkv3.txt | 71 +++++ + .../stlink/0483_374e_stlinkv3.txt | 182 ++++++++++++ + .../stlink/0483_374f_stlinkv3.txt | 212 ++++++++++++++ + .../stlink/0483_3752_stlinkv2.txt | 143 +++++++++ + .../stlink/0483_3753_stlinkv3.txt | 253 ++++++++++++++++ + .../xds110/0451_0451_ti_xds110.txt | 276 ++++++++++++++++++ + 19 files changed, 2606 insertions(+) + create mode 100644 doc/usb_adapters/cmsis_dap/0d28_0204_nxp_daplink.txt + create mode 100644 doc/usb_adapters/cmsis_dap/c251_2722_keil_ulink2.txt + create mode 100644 doc/usb_adapters/ft232r/0403_6001_ft232r.txt + create mode 100644 doc/usb_adapters/ftdi/0403_6010_ft2232h.txt + create mode 100644 doc/usb_adapters/ftdi/0403_cff8_amontec_jtagkey2.txt + create mode 100644 doc/usb_adapters/ftdi/09fb_6001_altera_blaster.txt + create mode 100644 doc/usb_adapters/icdi/1cbe_00fd_ti_icdi.txt + create mode 100644 doc/usb_adapters/jlink/1366_0101_segger_jlink_plus_10_1.txt + create mode 100644 doc/usb_adapters/nulink/0416_511d_nuvoton_nulink.txt + create mode 100644 doc/usb_adapters/nulink/0416_5200_nuvoton_nulink.txt + create mode 100644 doc/usb_adapters/stlink/0483_3744_stlinkv1.txt + create mode 100644 doc/usb_adapters/stlink/0483_3748_stlinkv2.txt + create mode 100644 doc/usb_adapters/stlink/0483_374b_stlinkv2.txt + create mode 100644 doc/usb_adapters/stlink/0483_374d_stlinkv3.txt + create mode 100644 doc/usb_adapters/stlink/0483_374e_stlinkv3.txt + create mode 100644 doc/usb_adapters/stlink/0483_374f_stlinkv3.txt + create mode 100644 doc/usb_adapters/stlink/0483_3752_stlinkv2.txt + create mode 100644 doc/usb_adapters/stlink/0483_3753_stlinkv3.txt + create mode 100644 doc/usb_adapters/xds110/0451_0451_ti_xds110.txt + +diff --git a/doc/usb_adapters/cmsis_dap/0d28_0204_nxp_daplink.txt b/doc/usb_adapters/cmsis_dap/0d28_0204_nxp_daplink.txt +new file mode 100644 +index 000000000..2ec0d58e2 +--- /dev/null ++++ b/doc/usb_adapters/cmsis_dap/0d28_0204_nxp_daplink.txt +@@ -0,0 +1,175 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: NXP FRDM-K64F ++ ++Bus 001 Device 006: ID 0d28:0204 NXP ARM mbed ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0d28 NXP ++ idProduct 0x0204 ARM mbed ++ bcdDevice 10.00 ++ iManufacturer 1 ARM ++ iProduct 2 DAPLink CMSIS-DAP ++ iSerial 3 0240000031754e45002f00199485002b6461000097969900 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0082 ++ bNumInterfaces 4 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 500mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 8 Mass Storage ++ bInterfaceSubClass 6 SCSI ++ bInterfaceProtocol 80 Bulk-Only ++ iInterface 7 USB_MSC ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 6 CMSIS-DAP ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.00 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 33 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 1 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 4 mbed Serial Port ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 4 mbed Serial Port ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x03 ++ call management ++ use DataInterface ++ bDataInterface 2 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 1 ++ bSlaveInterface 2 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0010 1x 16 bytes ++ bInterval 32 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 5 mbed Serial Port ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/cmsis_dap/c251_2722_keil_ulink2.txt b/doc/usb_adapters/cmsis_dap/c251_2722_keil_ulink2.txt +new file mode 100644 +index 000000000..520f7c553 +--- /dev/null ++++ b/doc/usb_adapters/cmsis_dap/c251_2722_keil_ulink2.txt +@@ -0,0 +1,72 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Standalone adapter ++ ++Bus 001 Device 010: ID c251:2722 Keil Software, Inc. Keil ULINK2 CMSIS-DAP ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0xc251 Keil Software, Inc. ++ idProduct 0x2722 ++ bcdDevice 1.00 ++ iManufacturer 1 Keil Software ++ iProduct 2 Keil ULINK2 CMSIS-DAP ++ iSerial 3 V0022U9E ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0029 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 4 CMSIS-DAP ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.00 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 33 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/ft232r/0403_6001_ft232r.txt b/doc/usb_adapters/ft232r/0403_6001_ft232r.txt +new file mode 100644 +index 000000000..8bfb058fd +--- /dev/null ++++ b/doc/usb_adapters/ft232r/0403_6001_ft232r.txt +@@ -0,0 +1,64 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: FT232RL ++# Chip: FT232RL ++ ++Bus 001 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 8 ++ idVendor 0x0403 Future Technology Devices International, Ltd ++ idProduct 0x6001 FT232 Serial (UART) IC ++ bcdDevice 6.00 ++ iManufacturer 1 FTDI ++ iProduct 2 FT232R USB UART ++ iSerial 3 A50285BI ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0020 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0xa0 ++ (Bus Powered) ++ Remote Wakeup ++ MaxPower 90mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 FT232R USB UART ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/ftdi/0403_6010_ft2232h.txt b/doc/usb_adapters/ftdi/0403_6010_ft2232h.txt +new file mode 100644 +index 000000000..8bb33e6e5 +--- /dev/null ++++ b/doc/usb_adapters/ftdi/0403_6010_ft2232h.txt +@@ -0,0 +1,103 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: Steppenprobe ++# Link: https://github.com/diegoherranz/steppenprobe ++# Chip: FT2232HL ++ ++Bus 001 Device 012: ID 0403:6010 Future Technology Devices International, Ltd FT2232C/D/H Dual UART/FIFO IC ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0x0403 Future Technology Devices International, Ltd ++ idProduct 0x6010 FT2232C/D/H Dual UART/FIFO IC ++ bcdDevice 7.00 ++ iManufacturer 1 FTDI ++ iProduct 2 Dual RS232-HS ++ iSerial 0 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0037 ++ bNumInterfaces 2 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 500mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 Dual RS232-HS ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 Dual RS232-HS ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/ftdi/0403_cff8_amontec_jtagkey2.txt b/doc/usb_adapters/ftdi/0403_cff8_amontec_jtagkey2.txt +new file mode 100644 +index 000000000..f056502ad +--- /dev/null ++++ b/doc/usb_adapters/ftdi/0403_cff8_amontec_jtagkey2.txt +@@ -0,0 +1,104 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Link: http://www.amontec.com ++# Casing: Hi-Speed JTAGkey-2 (c) 2009, Amontec ++# PCB: Amontec JTAGkey2 v5.3 ++# Chip: FT2232HQ ++ ++Bus 001 Device 017: ID 0403:cff8 Future Technology Devices International, Ltd Amontec JTAGkey ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0x0403 Future Technology Devices International, Ltd ++ idProduct 0xcff8 Amontec JTAGkey ++ bcdDevice 7.00 ++ iManufacturer 1 Amontec ++ iProduct 2 Amontec JTAGkey-2 ++ iSerial 3 53U2ML49 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0037 ++ bNumInterfaces 2 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 Amontec JTAGkey-2 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 Amontec JTAGkey-2 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/ftdi/09fb_6001_altera_blaster.txt b/doc/usb_adapters/ftdi/09fb_6001_altera_blaster.txt +new file mode 100644 +index 000000000..25f43a416 +--- /dev/null ++++ b/doc/usb_adapters/ftdi/09fb_6001_altera_blaster.txt +@@ -0,0 +1,64 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Clone www.terasic.com "USB Blaster" ++# PCB reports: "USB Blaster-B", "FOR ALTERA ONLY" ++# Chip: FT245BL ++ ++Bus 001 Device 005: ID 09fb:6001 Altera Blaster ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 1.10 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 8 ++ idVendor 0x09fb Altera ++ idProduct 0x6001 Blaster ++ bcdDevice 4.00 ++ iManufacturer 1 Altera ++ iProduct 2 USB-Blaster ++ iSerial 3 91f28492 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0020 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 150mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 USB-Blaster ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/icdi/1cbe_00fd_ti_icdi.txt b/doc/usb_adapters/icdi/1cbe_00fd_ti_icdi.txt +new file mode 100644 +index 000000000..14fc86fd6 +--- /dev/null ++++ b/doc/usb_adapters/icdi/1cbe_00fd_ti_icdi.txt +@@ -0,0 +1,156 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: TI Tiva C Series TM4C1294 Connected LaunchPad ++# ICDI firmware update to add OpenOCD support ++ ++Bus 001 Device 016: ID 1cbe:00fd Luminary Micro Inc. In-Circuit Debug Interface ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 1.10 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x1cbe Luminary Micro Inc. ++ idProduct 0x00fd In-Circuit Debug Interface ++ bcdDevice 1.00 ++ iManufacturer 1 Texas Instruments ++ iProduct 2 In-Circuit Debug Interface ++ iSerial 3 0F00CAC2 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0074 ++ bNumInterfaces 4 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 250mA ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 0 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 0 ++ CDC Header: ++ bcdCDC 1.10 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 0 ++ bSlaveInterface 1 ++ CDC Call Management: ++ bmCapabilities 0x01 ++ call management ++ bDataInterface 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0010 1x 16 bytes ++ bInterval 1 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 0 ++ bInterfaceClass 254 Application Specific Interface ++ bInterfaceSubClass 1 Device Firmware Update ++ bInterfaceProtocol 1 ++ iInterface 0 ++ Device Firmware Upgrade Interface Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bmAttributes 15 ++ Will Detach ++ Manifestation Tolerant ++ Upload Supported ++ Download Supported ++ wDetachTimeout 65535 milliseconds ++ wTransferSize 1024 bytes ++ bcdDFUVersion 1.10 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/jlink/1366_0101_segger_jlink_plus_10_1.txt b/doc/usb_adapters/jlink/1366_0101_segger_jlink_plus_10_1.txt +new file mode 100644 +index 000000000..fd31e9c78 +--- /dev/null ++++ b/doc/usb_adapters/jlink/1366_0101_segger_jlink_plus_10_1.txt +@@ -0,0 +1,71 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Standalone adapter, original Segger, HW version 10.1 ++ ++Bus 001 Device 005: ID 1366:0101 SEGGER J-Link PLUS ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0x1366 SEGGER ++ idProduct 0x0101 J-Link PLUS ++ bcdDevice 1.00 ++ iManufacturer 1 SEGGER ++ iProduct 2 J-Link ++ iSerial 3 123456 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0020 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 4 Configuration ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 5 BULK interface ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 1 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/nulink/0416_511d_nuvoton_nulink.txt b/doc/usb_adapters/nulink/0416_511d_nuvoton_nulink.txt +new file mode 100644 +index 000000000..fb4392351 +--- /dev/null ++++ b/doc/usb_adapters/nulink/0416_511d_nuvoton_nulink.txt +@@ -0,0 +1,142 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: nuvoTon NuMaker-PFM-M2351 ++# Adapter: ICE V3.0 ++ ++Bus 001 Device 013: ID 0416:511d Winbond Electronics Corp. Nuvoton Nu-Link1 ICE/VCOM ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 1.10 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0416 Winbond Electronics Corp. ++ idProduct 0x511d Nuvoton Nu-Link1 ICE/VCOM ++ bcdDevice 1.00 ++ iManufacturer 1 Nuvoton ++ iProduct 2 Nu-Link ++ iSerial 0 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x006b ++ bNumInterfaces 3 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.10 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 28 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 1 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 2 Nu-Link ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 0 ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 1 ++ CDC ACM: ++ bmCapabilities 0x00 ++ CDC Union: ++ bMasterInterface 1 ++ bSlaveInterface 2 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0008 1x 8 bytes ++ bInterval 255 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/nulink/0416_5200_nuvoton_nulink.txt b/doc/usb_adapters/nulink/0416_5200_nuvoton_nulink.txt +new file mode 100644 +index 000000000..1d8661f18 +--- /dev/null ++++ b/doc/usb_adapters/nulink/0416_5200_nuvoton_nulink.txt +@@ -0,0 +1,211 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: nuvoTon NuMaker-M483KG V1.1 ++# Adapter: Nu-Link2-Me V1.0 ++ ++Bus 001 Device 014: ID 0416:5200 Winbond Electronics Corp. Nuvoton Nu-Link2-ME ICE/MSC/VCOM ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0416 Winbond Electronics Corp. ++ idProduct 0x5200 Nuvoton Nu-Link2-ME ICE/MSC/VCOM ++ bcdDevice 0.00 ++ iManufacturer 1 Nuvoton ++ iProduct 2 Nu-Link2 Bulk ++ iSerial 6 13010000AAAAAAAAAAAAAAAAAAAAAAAA ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0099 ++ bNumInterfaces 5 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 1 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 3 Nu-Link2 VCOM ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 1 ++ CDC ACM: ++ bmCapabilities 0x00 ++ CDC Union: ++ bMasterInterface 1 ++ bSlaveInterface 2 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0100 1x 256 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0100 1x 256 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 4 Nu-Link2 HID ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.10 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 35 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x86 EP 6 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0400 1x 1024 bytes ++ bInterval 4 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x07 EP 7 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0400 1x 1024 bytes ++ bInterval 4 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 4 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 8 Mass Storage ++ bInterfaceSubClass 6 SCSI ++ bInterfaceProtocol 80 Bulk-Only ++ iInterface 5 Nu-Link2 MSC ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x88 EP 8 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x09 EP 9 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/stlink/0483_3744_stlinkv1.txt b/doc/usb_adapters/stlink/0483_3744_stlinkv1.txt +new file mode 100644 +index 000000000..b887f7971 +--- /dev/null ++++ b/doc/usb_adapters/stlink/0483_3744_stlinkv1.txt +@@ -0,0 +1,62 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Standalone adapter ++ ++Bus 001 Device 009: ID 0483:3744 STMicroelectronics ST-LINK/V1 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0x0483 STMicroelectronics ++ idProduct 0x3744 ST-LINK/V1 ++ bcdDevice 1.00 ++ iManufacturer 1 STMicroelectronics ++ iProduct 2 STM32 STLink ++ iSerial 3 0000001 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0020 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 8 Mass Storage ++ bInterfaceSubClass 6 SCSI ++ bInterfaceProtocol 80 Bulk-Only ++ iInterface 4 ST Link ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/stlink/0483_3748_stlinkv2.txt b/doc/usb_adapters/stlink/0483_3748_stlinkv2.txt +new file mode 100644 +index 000000000..ac6dfc7f6 +--- /dev/null ++++ b/doc/usb_adapters/stlink/0483_3748_stlinkv2.txt +@@ -0,0 +1,72 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# ST-Link/V2 standalone or ST-Link/V2 in firmware update mode ++ ++Bus 001 Device 006: ID 0483:3748 STMicroelectronics ST-LINK/V2 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0x0483 STMicroelectronics ++ idProduct 0x3748 ST-LINK/V2 ++ bcdDevice 1.00 ++ iManufacturer 1 STMicroelectronics ++ iProduct 2 STM32 STLink ++ iSerial 3 0668FF323637414257071827 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0027 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 3 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 4 ST Link ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/stlink/0483_374b_stlinkv2.txt b/doc/usb_adapters/stlink/0483_374b_stlinkv2.txt +new file mode 100644 +index 000000000..cc0156d74 +--- /dev/null ++++ b/doc/usb_adapters/stlink/0483_374b_stlinkv2.txt +@@ -0,0 +1,173 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: ST Nucleo F411 ++ ++Bus 001 Device 007: ID 0483:374b STMicroelectronics ST-LINK/V2.1 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0483 STMicroelectronics ++ idProduct 0x374b ST-LINK/V2.1 ++ bcdDevice 1.00 ++ iManufacturer 1 STMicroelectronics ++ iProduct 2 STM32 STLink ++ iSerial 3 066EFF373535503457062922 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0080 ++ bNumInterfaces 4 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 3 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 4 ST-Link Debug ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0020 1x 32 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 8 Mass Storage ++ bInterfaceSubClass 6 SCSI ++ bInterfaceProtocol 80 Bulk-Only ++ iInterface 5 ST-Link mass storage ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x03 EP 3 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 2 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 6 ST-Link VCP Ctrl ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 6 ST-Link VCP Ctrl ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 3 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 2 ++ bSlaveInterface 3 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0002 1x 2 bytes ++ bInterval 255 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 7 ST-Link VCP Data ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x05 EP 5 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0008 1x 8 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0010 1x 16 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/stlink/0483_374d_stlinkv3.txt b/doc/usb_adapters/stlink/0483_374d_stlinkv3.txt +new file mode 100644 +index 000000000..e964872c3 +--- /dev/null ++++ b/doc/usb_adapters/stlink/0483_374d_stlinkv3.txt +@@ -0,0 +1,71 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# ST-Link/V3 in firmware update mode ++ ++Bus 001 Device 009: ID 0483:374d STMicroelectronics STLINK-V3 Loader ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0x0483 STMicroelectronics ++ idProduct 0x374d STLINK-V3 Loader ++ bcdDevice 2.00 ++ iManufacturer 1 STMicroelectronics ++ iProduct 2 STM32 ST-LINK/V3 ++ iSerial 3 003500463137510239383538 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0020 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 4 DFU Config ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 5 ST-LINK/V3 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 1 ++Device Status: 0x0001 ++ Self Powered +diff --git a/doc/usb_adapters/stlink/0483_374e_stlinkv3.txt b/doc/usb_adapters/stlink/0483_374e_stlinkv3.txt +new file mode 100644 +index 000000000..55c968cce +--- /dev/null ++++ b/doc/usb_adapters/stlink/0483_374e_stlinkv3.txt +@@ -0,0 +1,182 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: ST Nucleo-H745AI-Q ++ ++Bus 001 Device 008: ID 0483:374e STMicroelectronics STLINK-V3 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0483 STMicroelectronics ++ idProduct 0x374e STLINK-V3 ++ bcdDevice 1.00 ++ iManufacturer 1 STMicroelectronics ++ iProduct 2 STLINK-V3 ++ iSerial 3 005100313137511039383538 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0080 ++ bNumInterfaces 4 ++ bConfigurationValue 1 ++ iConfiguration 4 Default Config ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 500mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 3 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 5 ST-Link Debug ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 8 Mass Storage ++ bInterfaceSubClass 6 SCSI ++ bInterfaceProtocol 80 Bulk-Only ++ iInterface 6 ST-Link mass storage ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x03 EP 3 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 2 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 7 ST-Link VCP Ctrl ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 7 ST-Link VCP Ctrl ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 3 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 2 ++ bSlaveInterface 3 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x000a 1x 10 bytes ++ bInterval 16 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 8 ST-Link VCP Data ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x05 EP 5 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/stlink/0483_374f_stlinkv3.txt b/doc/usb_adapters/stlink/0483_374f_stlinkv3.txt +new file mode 100644 +index 000000000..1974001c7 +--- /dev/null ++++ b/doc/usb_adapters/stlink/0483_374f_stlinkv3.txt +@@ -0,0 +1,212 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Standalone adapter ++ ++Bus 001 Device 008: ID 0483:374f STMicroelectronics STLINK-V3 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0483 STMicroelectronics ++ idProduct 0x374f STLINK-V3 ++ bcdDevice 1.00 ++ iManufacturer 1 STMicroelectronics ++ iProduct 2 STLINK-V3 ++ iSerial 3 003500463137510239383538 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0097 ++ bNumInterfaces 5 ++ bConfigurationValue 1 ++ iConfiguration 4 Default Config ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 500mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 3 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 5 ST-Link Debug ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 8 Mass Storage ++ bInterfaceSubClass 6 SCSI ++ bInterfaceProtocol 80 Bulk-Only ++ iInterface 6 ST-Link mass storage ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x03 EP 3 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 2 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 7 ST-Link VCP Ctrl ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 7 ST-Link VCP Ctrl ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 3 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 2 ++ bSlaveInterface 3 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x000a 1x 10 bytes ++ bInterval 16 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 8 ST-Link VCP Data ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x05 EP 5 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 4 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 9 ST-Link Bridge ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x86 EP 6 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x06 EP 6 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/stlink/0483_3752_stlinkv2.txt b/doc/usb_adapters/stlink/0483_3752_stlinkv2.txt +new file mode 100644 +index 000000000..798b5276e +--- /dev/null ++++ b/doc/usb_adapters/stlink/0483_3752_stlinkv2.txt +@@ -0,0 +1,143 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: ST STM32MP157f-DK2 ++ ++Bus 001 Device 005: ID 0483:3752 STMicroelectronics ST-LINK/V2.1 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0483 STMicroelectronics ++ idProduct 0x3752 ST-LINK/V2.1 ++ bcdDevice 1.00 ++ iManufacturer 1 STMicroelectronics ++ iProduct 2 STM32 STLink ++ iSerial 3 0668FF323637414257071827 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0069 ++ bNumInterfaces 3 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 300mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 3 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 4 ST-Link Debug ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0020 1x 32 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 1 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 6 ST-Link VCP Ctrl ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 6 ST-Link VCP Ctrl ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 2 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 1 ++ bSlaveInterface 2 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0008 1x 8 bytes ++ bInterval 16 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 7 ST-Link VCP Data ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x05 EP 5 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/stlink/0483_3753_stlinkv3.txt b/doc/usb_adapters/stlink/0483_3753_stlinkv3.txt +new file mode 100644 +index 000000000..e3a951f99 +--- /dev/null ++++ b/doc/usb_adapters/stlink/0483_3753_stlinkv3.txt +@@ -0,0 +1,253 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board STM32MP135F-DK ++ ++Bus 001 Device 011: ID 0483:3753 STMicroelectronics STLINK-V3 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0483 STMicroelectronics ++ idProduct 0x3753 STLINK-V3 ++ bcdDevice 1.00 ++ iManufacturer 1 STMicroelectronics ++ iProduct 2 STLINK-V3 ++ iSerial 3 001000294741500120383733 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x00c2 ++ bNumInterfaces 6 ++ bConfigurationValue 1 ++ iConfiguration 4 Default Config ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 300mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 3 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 5 ST-Link Debug ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 1 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 7 ST-Link VCP Ctrl ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 7 ST-Link VCP Ctrl ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 2 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 1 ++ bSlaveInterface 2 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x000a 1x 10 bytes ++ bInterval 16 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 8 ST-Link VCP Data ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x05 EP 5 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 9 ST-Link Bridge ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x86 EP 6 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x06 EP 6 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 4 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 10 ST-Link VCP2 Ctrl ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 4 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 10 ST-Link VCP2 Ctrl ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 5 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 4 ++ bSlaveInterface 5 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x000a 1x 10 bytes ++ bInterval 16 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 5 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 11 ST-Link VCP2 Data ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x07 EP 7 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x87 EP 7 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/xds110/0451_0451_ti_xds110.txt b/doc/usb_adapters/xds110/0451_0451_ti_xds110.txt +new file mode 100644 +index 000000000..9ad9b7dbf +--- /dev/null ++++ b/doc/usb_adapters/xds110/0451_0451_ti_xds110.txt +@@ -0,0 +1,276 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Board: TI CC2650 LaunchPad ++ ++Bus 001 Device 005: ID 0451:bef3 Texas Instruments, Inc. CC1352R1 Launchpad ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 1.10 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x0451 Texas Instruments, Inc. ++ idProduct 0xbef3 CC1352R1 Launchpad ++ bcdDevice 1.00 ++ iManufacturer 1 Texas Instruments ++ iProduct 2 XDS110 (03.00.00.13) Embed with CMSIS-DAP ++ iSerial 3 L1002566 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x00db ++ bNumInterfaces 7 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 500mA ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 0 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 0 ++ CDC Header: ++ bcdCDC 1.10 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 0 ++ bSlaveInterface 1 ++ CDC Call Management: ++ bmCapabilities 0x01 ++ call management ++ bDataInterface 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0010 1x 16 bytes ++ bInterval 1 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 3 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 0 ++ CDC Header: ++ bcdCDC 1.10 ++ CDC ACM: ++ bmCapabilities 0x06 ++ sends break ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 3 ++ bSlaveInterface 4 ++ CDC Call Management: ++ bmCapabilities 0x01 ++ call management ++ bDataInterface 4 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0010 1x 16 bytes ++ bInterval 1 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 4 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x03 EP 3 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 5 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 6 XDS110 CMSIS-DAP ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.11 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 24 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x86 EP 6 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 6 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x05 EP 5 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x87 EP 7 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0027-doc-usb_adapters-add-other-adapters.patch b/meta-oe/recipes-devtools/openocd/openocd/0027-doc-usb_adapters-add-other-adapters.patch new file mode 100644 index 000000000..97f25245c --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0027-doc-usb_adapters-add-other-adapters.patch @@ -0,0 +1,1326 @@ +From 6d76a915214f06a4960710ae171434265409a705 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sat, 22 Oct 2022 17:58:28 +0200 +Subject: [PATCH] doc: usb_adapters: add other adapters + +Mainly get from web or from OpenOCD users + +Change-Id: Id4d6354bc9b6972622adfacf3549c7c3e0549bc2 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7298 +Tested-by: jenkins +--- + .../cmsis_dap/04b4_f155_cypress_kitprog3.txt | 173 ++++++++++++++++++ + .../cmsis_dap/1a6a_2000_spansion_sk_fm4.txt | 143 +++++++++++++++ + .../cmsis_dap/2a86_8011_wch_link.txt | 143 +++++++++++++++ + .../cmsis_dap/c251_2723_keil_ulink_me.txt | 72 ++++++++ + .../cmsis_dap/c251_2750_keil_ulinkplus.txt | 161 ++++++++++++++++ + .../cmsis_dap/c251_f001_jixin.pro.txt | 143 +++++++++++++++ + .../ftdi/0403_6014_digilent_hs2.txt | 71 +++++++ + .../ftdi/9e88_9e8f_sheevaplug_jtagkey.txt | 92 ++++++++++ + .../jlink/1366_0101_segger_jlink.txt | 62 +++++++ + .../kitprog/04b4_f139_cypress_kitprog.txt | 172 +++++++++++++++++ + 10 files changed, 1232 insertions(+) + create mode 100644 doc/usb_adapters/cmsis_dap/04b4_f155_cypress_kitprog3.txt + create mode 100644 doc/usb_adapters/cmsis_dap/1a6a_2000_spansion_sk_fm4.txt + create mode 100644 doc/usb_adapters/cmsis_dap/2a86_8011_wch_link.txt + create mode 100644 doc/usb_adapters/cmsis_dap/c251_2723_keil_ulink_me.txt + create mode 100644 doc/usb_adapters/cmsis_dap/c251_2750_keil_ulinkplus.txt + create mode 100644 doc/usb_adapters/cmsis_dap/c251_f001_jixin.pro.txt + create mode 100644 doc/usb_adapters/ftdi/0403_6014_digilent_hs2.txt + create mode 100644 doc/usb_adapters/ftdi/9e88_9e8f_sheevaplug_jtagkey.txt + create mode 100644 doc/usb_adapters/jlink/1366_0101_segger_jlink.txt + create mode 100644 doc/usb_adapters/kitprog/04b4_f139_cypress_kitprog.txt + +diff --git a/doc/usb_adapters/cmsis_dap/04b4_f155_cypress_kitprog3.txt b/doc/usb_adapters/cmsis_dap/04b4_f155_cypress_kitprog3.txt +new file mode 100644 +index 000000000..3109c6912 +--- /dev/null ++++ b/doc/usb_adapters/cmsis_dap/04b4_f155_cypress_kitprog3.txt +@@ -0,0 +1,173 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# KitProg3 Firmware 1.01 ++# Has inconsistent class code 0 for CMSIS-DAP interface ++ ++Bus 002 Device 017: ID 04b4:f155 Cypress Semiconductor Corp. ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ? ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 8 ++ idVendor 0x04b4 Cypress Semiconductor Corp. ++ idProduct 0xf155 ++ bcdDevice 1.01 ++ iManufacturer 1 Cypress Semiconductor ++ iProduct 6 KitProg3 CMSIS-DAP ++ iSerial 128 102015B003137400 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 130 ++ bNumInterfaces 4 ++ bConfigurationValue 1 ++ iConfiguration 11 KitProg3 CMSIS-DAP ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 400mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 0 (Defined at Interface level) ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 6 KitProg3 CMSIS-DAP ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 No Subclass ++ bInterfaceProtocol 0 None ++ iInterface 12 KitProg3 bridge ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.11 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 43 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x86 EP 6 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x07 EP 7 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 2 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 0 None ++ iFunction 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 15 KitProg3 USBUART ++ CDC Header: ++ bcdCDC 1.10 ++ CDC ACM: ++ bmCapabilities 0x02 ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 2 ++ bSlaveInterface 3 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 3 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0008 1x 8 bytes ++ bInterval 2 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 Unused ++ bInterfaceProtocol 0 ++ iInterface 4 KitProg3 USBUART ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x05 EP 5 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/cmsis_dap/1a6a_2000_spansion_sk_fm4.txt b/doc/usb_adapters/cmsis_dap/1a6a_2000_spansion_sk_fm4.txt +new file mode 100644 +index 000000000..368ec2a2b +--- /dev/null ++++ b/doc/usb_adapters/cmsis_dap/1a6a_2000_spansion_sk_fm4.txt +@@ -0,0 +1,143 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Reported in https://en.opensuse.org/User:A_faerber/SK-FM4-176L-S6E2CC ++ ++Bus 002 Device 009: ID 1a6a:2000 Spansion Inc. ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 1.01 ++ bDeviceClass 0 (Defined at Interface level) ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0x1a6a Spansion Inc. ++ idProduct 0x2000 ++ bcdDevice 1.60 ++ iManufacturer 1 Spansion ++ iProduct 2 Spansion CMSIS-DAP + COM Port ++ iSerial 0 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 107 ++ bNumInterfaces 3 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x00 ++ (Missing must-be-set bit!) ++ (Bus Powered) ++ MaxPower 62mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 No Subclass ++ bInterfaceProtocol 0 None ++ iInterface 4 Spansion CMSIS-DAP ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.11 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 29 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 1 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 5 Spansion USB Serial Port ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 1 AT-commands (v.25ter) ++ iInterface 0 ++ CDC Header: ++ bcdCDC 10.01 ++ CDC ACM: ++ bmCapabilities 0x00 ++ CDC Union: ++ bMasterInterface 1 ++ bSlaveInterface 2 ++ CDC Call Management: ++ bmCapabilities 0x01 ++ call management ++ bDataInterface 2 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 255 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 Unused ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/cmsis_dap/2a86_8011_wch_link.txt b/doc/usb_adapters/cmsis_dap/2a86_8011_wch_link.txt +new file mode 100644 +index 000000000..f27d9932f +--- /dev/null ++++ b/doc/usb_adapters/cmsis_dap/2a86_8011_wch_link.txt +@@ -0,0 +1,143 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Reported in https://github.com/pyocd/pyOCD/issues/1395 ++ ++Bus 003 Device 118: ID 2a86:8011 wch.cn WCH-Link ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 8 ++ idVendor 0x2a86 ++ idProduct 0x8011 ++ bcdDevice 1.00 ++ iManufacturer 1 wch.cn ++ iProduct 2 WCH-Link ++ iSerial 3 0001A0000001 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x006b ++ bNumInterfaces 3 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 500mA ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 0 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 4 QYF CMSIS-DAP ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 0 ++ iInterface 4 QYF CMSIS-DAP ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x01 ++ call management ++ bDataInterface 1 ++ CDC ACM: ++ bmCapabilities 0x02 ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 0 ++ bSlaveInterface 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 2 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 5 (error) ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x03 EP 3 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 6 QYF CMSIS-DAP ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.00 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 33 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/cmsis_dap/c251_2723_keil_ulink_me.txt b/doc/usb_adapters/cmsis_dap/c251_2723_keil_ulink_me.txt +new file mode 100644 +index 000000000..df2b9243e +--- /dev/null ++++ b/doc/usb_adapters/cmsis_dap/c251_2723_keil_ulink_me.txt +@@ -0,0 +1,72 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Reported in https://stackoverflow.com/questions/27087281/jtag-adapter-ulink-me-and-openocd-on-archlinux ++ ++Bus 005 Device 026: ID c251:2723 Keil Software, Inc. ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 (Defined at Interface level) ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0xc251 Keil Software, Inc. ++ idProduct 0x2723 ++ bcdDevice 1.00 ++ iManufacturer 1 Keil Software ++ iProduct 2 Keil ULINK-ME CMSIS-DAP ++ iSerial 3 M0489MAE ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 41 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 No Subclass ++ bInterfaceProtocol 0 None ++ iInterface 4 CMSIS-DAP ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.00 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 33 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/cmsis_dap/c251_2750_keil_ulinkplus.txt b/doc/usb_adapters/cmsis_dap/c251_2750_keil_ulinkplus.txt +new file mode 100644 +index 000000000..4504ef0eb +--- /dev/null ++++ b/doc/usb_adapters/cmsis_dap/c251_2750_keil_ulinkplus.txt +@@ -0,0 +1,161 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# firmware 2.0.11 ++ ++Bus 001 Device 005: ID c251:2750 Keil Software, Inc. ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 (Defined at Interface level) ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0xc251 Keil Software, Inc. ++ idProduct 0x2750 ++ bcdDevice 1.00 ++ iManufacturer 1 KEIL - Tools By ARM ++ iProduct 2 Keil ULINKplus ++ iSerial 3 L78440715A ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 101 ++ bNumInterfaces 4 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 500mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 3 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 4 ULINKplus CMSIS-DAP ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 5 ULINKplus Digital I/O ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 6 ULINKplus Analog I/O ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x03 EP 3 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 7 ULINKplus Power Probe ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x84 EP 4 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 (Defined at Interface level) ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/cmsis_dap/c251_f001_jixin.pro.txt b/doc/usb_adapters/cmsis_dap/c251_f001_jixin.pro.txt +new file mode 100644 +index 000000000..c08f679a6 +--- /dev/null ++++ b/doc/usb_adapters/cmsis_dap/c251_f001_jixin.pro.txt +@@ -0,0 +1,143 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Reported in https://sourceforge.net/p/openocd/tickets/368/ ++ ++Bus 001 Device 008: ID c251:f001 Keil Software, Inc. ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ? ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0xc251 Keil Software, Inc. ++ idProduct 0xf001 ++ bcdDevice 1.00 ++ iManufacturer 1 jixin.pro ++ iProduct 2 CMSIS-DAP_LU ++ iSerial 3 LU_2022_8888 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 107 ++ bNumInterfaces 3 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 100mA ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 0 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 1 AT-commands (v.25ter) ++ iFunction 4 CMSIS-DAP CDC ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 0 None ++ iInterface 4 CMSIS-DAP CDC ++ CDC Header: ++ bcdCDC 1.10 ++ CDC Call Management: ++ bmCapabilities 0x01 ++ call management ++ bDataInterface 1 ++ CDC ACM: ++ bmCapabilities 0x02 ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 0 ++ bSlaveInterface 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 2 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 Unused ++ bInterfaceProtocol 0 ++ iInterface 5 CMSIS-DAP DCI ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 No Subclass ++ bInterfaceProtocol 0 None ++ iInterface 6 CMSIS-DAP_LU ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.00 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 33 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x03 EP 3 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/ftdi/0403_6014_digilent_hs2.txt b/doc/usb_adapters/ftdi/0403_6014_digilent_hs2.txt +new file mode 100644 +index 000000000..68fc119e1 +--- /dev/null ++++ b/doc/usb_adapters/ftdi/0403_6014_digilent_hs2.txt +@@ -0,0 +1,71 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Reported in https://sourceforge.net/p/openocd/tickets/357/ ++ ++Bus 001 Device 084: ID 0403:6014 Future Technology Devices International, Ltd FT232H Single HS USB-UART/FIFO IC ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ idVendor 0x0403 Future Technology Devices International, Ltd ++ idProduct 0x6014 FT232H Single HS USB-UART/FIFO IC ++ bcdDevice 9.00 ++ iManufacturer 1 Digilent ++ iProduct 2 Digilent USB Device ++ iSerial 3 210249AFCD0B ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0020 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 500mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 Digilent USB Device ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0200 1x 512 bytes ++ bInterval 0 ++Device Qualifier (for other device speed): ++ bLength 10 ++ bDescriptorType 6 ++ bcdUSB 2.00 ++ bDeviceClass 0 ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 64 ++ bNumConfigurations 1 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/ftdi/9e88_9e8f_sheevaplug_jtagkey.txt b/doc/usb_adapters/ftdi/9e88_9e8f_sheevaplug_jtagkey.txt +new file mode 100644 +index 000000000..c61044335 +--- /dev/null ++++ b/doc/usb_adapters/ftdi/9e88_9e8f_sheevaplug_jtagkey.txt +@@ -0,0 +1,92 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Reported in https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=837989 ++ ++Bus 003 Device 002: ID 9e88:9e8f ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 0 (Defined at Interface level) ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 8 ++ idVendor 0x9e88 ++ idProduct 0x9e8f ++ bcdDevice 5.00 ++ iManufacturer 1 FTDI ++ iProduct 2 SheevaPlug JTAGKey FT2232D B ++ iSerial 3 FTU85Z4Y ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 55 ++ bNumInterfaces 2 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0xc0 ++ Self Powered ++ MaxPower 0mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 SheevaPlug JTAGKey FT2232D B ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 2 SheevaPlug JTAGKey FT2232D B ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) +diff --git a/doc/usb_adapters/jlink/1366_0101_segger_jlink.txt b/doc/usb_adapters/jlink/1366_0101_segger_jlink.txt +new file mode 100644 +index 000000000..8fa4e7d29 +--- /dev/null ++++ b/doc/usb_adapters/jlink/1366_0101_segger_jlink.txt +@@ -0,0 +1,62 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Reported in https://forums.gentoo.org/viewtopic-t-781442-start-0.html ++ ++Bus 002 Device 002: ID 1366:0101 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 1.10 ++ bDeviceClass 0 (Defined at Interface level) ++ bDeviceSubClass 0 ++ bDeviceProtocol 0 ++ bMaxPacketSize0 8 ++ idVendor 0x1366 ++ idProduct 0x0101 ++ bcdDevice 0.01 ++ iManufacturer 1 SEGGER ++ iProduct 2 J-Link ++ iSerial 3 123456 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 32 ++ bNumInterfaces 1 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0xc0 ++ Self Powered ++ MaxPower 100mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 255 Vendor Specific Protocol ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0001 ++ Self Powered +diff --git a/doc/usb_adapters/kitprog/04b4_f139_cypress_kitprog.txt b/doc/usb_adapters/kitprog/04b4_f139_cypress_kitprog.txt +new file mode 100644 +index 000000000..e3430d87e +--- /dev/null ++++ b/doc/usb_adapters/kitprog/04b4_f139_cypress_kitprog.txt +@@ -0,0 +1,172 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Reported in http://false.ekta.is/tag/unboxing/ ++ ++Bus 003 Device 011: ID 04b4:f139 Cypress Semiconductor Corp. ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ? ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 8 ++ idVendor 0x04b4 Cypress Semiconductor Corp. ++ idProduct 0xf139 ++ bcdDevice 2.0b ++ iManufacturer 1 Cypress Semiconductor ++ iProduct 2 Cypress KitProg ++ iSerial 128 1C210338012E4400 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 130 ++ bNumInterfaces 4 ++ bConfigurationValue 1 ++ iConfiguration 2 Cypress KitProg ++ bmAttributes 0x80 ++ (Bus Powered) ++ MaxPower 400mA ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 3 Human Interface Device ++ bInterfaceSubClass 0 No Subclass ++ bInterfaceProtocol 0 None ++ iInterface 3 KitBridge ++ HID Device Descriptor: ++ bLength 9 ++ bDescriptorType 33 ++ bcdHID 1.11 ++ bCountryCode 0 Not supported ++ bNumDescriptors 1 ++ bDescriptorType 34 Report ++ wDescriptorLength 43 ++ Report Descriptors: ++ ** UNAVAILABLE ** ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x04 EP 4 OUT ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 0 ++ bInterfaceProtocol 0 ++ iInterface 5 KitProg Programmer ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 2 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 0 ++ bFunctionProtocol 0 ++ iFunction 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 0 None ++ iInterface 4 KitProg USBUART ++ CDC Header: ++ bcdCDC 1.10 ++ CDC ACM: ++ bmCapabilities 0x02 ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 2 ++ bSlaveInterface 1 ++ CDC Call Management: ++ bmCapabilities 0x00 ++ bDataInterface 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x85 EP 5 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0008 1x 8 bytes ++ bInterval 2 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 3 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 0 Unused ++ bInterfaceProtocol 0 ++ iInterface 4 KitProg USBUART ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x86 EP 6 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x07 EP 7 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 0 ++Device Status: 0x0000 ++ (Bus Powered) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0028-tools-add-disassembler-helper-for-files-.inc.patch b/meta-oe/recipes-devtools/openocd/openocd/0028-tools-add-disassembler-helper-for-files-.inc.patch new file mode 100644 index 000000000..1984e59c0 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0028-tools-add-disassembler-helper-for-files-.inc.patch @@ -0,0 +1,80 @@ +From 9dac3b247b43d8b91821560b7c99fbd33d736419 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 13 Nov 2022 15:46:19 +0100 +Subject: [PATCH] tools: add disassembler helper for files .inc + +We are moving the binary helpers in files .inc in contrib/loaders/ +but we have no support to disassemble them for checking their +content, nor documentation to give any hint. + +Add a simple script that uses objdump to directly disassemble a +file .inc +Use Cortex-M settings as default, but provide the flexibility to +reuse the script for any other target CPU. + +Change-Id: I12e79580f2936b1622fb7231d9a2484a763ba72a +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7347 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + tools/disassemble_inc.sh | 50 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + create mode 100755 tools/disassemble_inc.sh + +diff --git a/tools/disassemble_inc.sh b/tools/disassemble_inc.sh +new file mode 100755 +index 000000000..d4b5f80dc +--- /dev/null ++++ b/tools/disassemble_inc.sh +@@ -0,0 +1,50 @@ ++#!/bin/sh ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++# Simple script to disassemble a file .inc generated by ++# src/helper/bin2char.sh ++# Can be useful to check the correctness of the file .inc ++# ++# By default it decodes ARM thumb little-endian, e.g. cortex-m. ++# Set CROSS_COMPILE for other toolchains. ++# Set OBJDUMP_FLAGS for different objdump flags. ++# ++# Usage: ++# contrib/loaders/disassemble_inc.sh file.inc ++ ++default_CROSS_COMPILE="arm-none-eabi-" ++default_OBJDUMP_FLAGS="-m arm -EL -M force-thumb" ++ ++if [ $# != 1 -o ! -f "$1" ]; then ++ echo "Usage:" ++ echo " $0 path/to/file.inc" ++ echo "" ++ echo "Set CROSS_COMPILE and/or OBJDUMP_FLAGS to override current default:" ++ echo " export CROSS_COMPILE=\"${default_CROSS_COMPILE}\"" ++ echo " export OBJDUMP_FLAGS=\"${default_OBJDUMP_FLAGS}\"" ++ exit 1 ++fi ++ ++if [ -z "${CROSS_COMPILE}" ]; then ++ CROSS_COMPILE="${default_CROSS_COMPILE}" ++fi ++ ++if [ -z "${OBJDUMP_FLAGS}" ]; then ++ OBJDUMP_FLAGS="${default_OBJDUMP_FLAGS}" ++fi ++ ++perl -v > /dev/null 2>&1 ++if [ $? != 0 ]; then ++ echo "Error: 'perl' interpreter not available." ++ exit 1 ++fi ++ ++tmpfile=$(mktemp --suffix=.bin) ++ ++echo "Disassemble $1:" ++echo "${CROSS_COMPILE}objdump ${OBJDUMP_FLAGS} -b binary -D ${tmpfile}" ++ ++perl -e 'while (<>){while ($_=~/(0x..)/g){print chr(hex($1));}}' $1 > ${tmpfile} ++${CROSS_COMPILE}objdump ${OBJDUMP_FLAGS} -b binary -D ${tmpfile} ++ ++rm ${tmpfile} diff --git a/meta-oe/recipes-devtools/openocd/openocd/0029-jtag-drivers-cmsis_dap-move-pending-request-FIFO.patch b/meta-oe/recipes-devtools/openocd/openocd/0029-jtag-drivers-cmsis_dap-move-pending-request-FIFO.patch new file mode 100644 index 000000000..81d0828ca --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0029-jtag-drivers-cmsis_dap-move-pending-request-FIFO.patch @@ -0,0 +1,269 @@ +From 128736d23f0e92a245d51c10e889ed3e6da4c2b1 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sat, 19 Nov 2022 06:57:56 +0100 +Subject: [PATCH] jtag/drivers/cmsis_dap: move pending request FIFO + +Move all pending request FIFO related variables to +the struct cmsis_dap + +Pure refactoring, no functional changes. + +Signed-off-by: Tomas Vanek +Change-Id: I2cea9c1e265ac102ec0f314767b8b9afdcda9ee9 +Reviewed-on: https://review.openocd.org/c/openocd/+/7360 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/cmsis_dap.c | 91 +++++++++++++++--------------------- + src/jtag/drivers/cmsis_dap.h | 24 +++++++++- + 2 files changed, 59 insertions(+), 56 deletions(-) + +diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c +index 44a7dd8cb..c2f01f33d 100644 +--- a/src/jtag/drivers/cmsis_dap.c ++++ b/src/jtag/drivers/cmsis_dap.c +@@ -209,17 +209,6 @@ static const char * const info_caps_str[INFO_CAPS__NUM_CAPS] = { + "UART via USB COM port supported", + }; + +-struct pending_transfer_result { +- uint8_t cmd; +- uint32_t data; +- void *buffer; +-}; +- +-struct pending_request_block { +- struct pending_transfer_result *transfers; +- int transfer_count; +-}; +- + struct pending_scan_result { + /** Offset in bytes in the CMD_DAP_JTAG_SEQ response buffer. */ + unsigned first; +@@ -231,16 +220,8 @@ struct pending_scan_result { + unsigned buffer_offset; + }; + +-/* Up to MIN(packet_count, MAX_PENDING_REQUESTS) requests may be issued +- * until the first response arrives */ +-#define MAX_PENDING_REQUESTS 3 +- +-/* Pending requests are organized as a FIFO - circular buffer */ + /* Each block in FIFO can contain up to pending_queue_len transfers */ + static int pending_queue_len; +-static struct pending_request_block pending_fifo[MAX_PENDING_REQUESTS]; +-static int pending_fifo_put_idx, pending_fifo_get_idx; +-static int pending_fifo_block_count; + + /* pointers to buffers that will receive jtag scan results on the next flush */ + #define MAX_PENDING_SCAN_RESULTS 256 +@@ -314,8 +295,8 @@ static void cmsis_dap_close(struct cmsis_dap *dap) + cmsis_dap_handle = NULL; + + for (int i = 0; i < MAX_PENDING_REQUESTS; i++) { +- free(pending_fifo[i].transfers); +- pending_fifo[i].transfers = NULL; ++ free(dap->pending_fifo[i].transfers); ++ dap->pending_fifo[i].transfers = NULL; + } + } + +@@ -337,14 +318,14 @@ static void cmsis_dap_flush_read(struct cmsis_dap *dap) + /* Send a message and receive the reply */ + static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen) + { +- if (pending_fifo_block_count) { +- LOG_ERROR("pending %d blocks, flushing", pending_fifo_block_count); +- while (pending_fifo_block_count) { ++ if (dap->pending_fifo_block_count) { ++ LOG_ERROR("pending %u blocks, flushing", dap->pending_fifo_block_count); ++ while (dap->pending_fifo_block_count) { + dap->backend->read(dap, 10); +- pending_fifo_block_count--; ++ dap->pending_fifo_block_count--; + } +- pending_fifo_put_idx = 0; +- pending_fifo_get_idx = 0; ++ dap->pending_fifo_put_idx = 0; ++ dap->pending_fifo_get_idx = 0; + } + + uint8_t current_cmd = cmsis_dap_handle->command[0]; +@@ -763,9 +744,10 @@ static int cmsis_dap_cmd_dap_swo_data( + static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) + { + uint8_t *command = cmsis_dap_handle->command; +- struct pending_request_block *block = &pending_fifo[pending_fifo_put_idx]; ++ struct pending_request_block *block = &dap->pending_fifo[dap->pending_fifo_put_idx]; + +- LOG_DEBUG_IO("Executing %d queued transactions from FIFO index %d", block->transfer_count, pending_fifo_put_idx); ++ LOG_DEBUG_IO("Executing %d queued transactions from FIFO index %u", ++ block->transfer_count, dap->pending_fifo_put_idx); + + if (queued_retval != ERROR_OK) { + LOG_DEBUG("Skipping due to previous errors: %d", queued_retval); +@@ -824,10 +806,10 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) + queued_retval = ERROR_OK; + } + +- pending_fifo_put_idx = (pending_fifo_put_idx + 1) % dap->packet_count; +- pending_fifo_block_count++; +- if (pending_fifo_block_count > dap->packet_count) +- LOG_ERROR("too much pending writes %d", pending_fifo_block_count); ++ dap->pending_fifo_put_idx = (dap->pending_fifo_put_idx + 1) % dap->packet_count; ++ dap->pending_fifo_block_count++; ++ if (dap->pending_fifo_block_count > dap->packet_count) ++ LOG_ERROR("too much pending writes %u", dap->pending_fifo_block_count); + + return; + +@@ -837,9 +819,9 @@ skip: + + static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms) + { +- struct pending_request_block *block = &pending_fifo[pending_fifo_get_idx]; ++ struct pending_request_block *block = &dap->pending_fifo[dap->pending_fifo_get_idx]; + +- if (pending_fifo_block_count == 0) ++ if (dap->pending_fifo_block_count == 0) + LOG_ERROR("no pending write"); + + /* get reply */ +@@ -880,8 +862,8 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms) + LOG_ERROR("CMSIS-DAP transfer count mismatch: expected %d, got %d", + block->transfer_count, transfer_count); + +- LOG_DEBUG_IO("Received results of %d queued transactions FIFO index %d", +- transfer_count, pending_fifo_get_idx); ++ LOG_DEBUG_IO("Received results of %d queued transactions FIFO index %u timeout %i", ++ transfer_count, dap->pending_fifo_get_idx, timeout_ms); + size_t idx = 3; + for (int i = 0; i < transfer_count; i++) { + struct pending_transfer_result *transfer = &(block->transfers[i]); +@@ -907,22 +889,22 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms) + + skip: + block->transfer_count = 0; +- pending_fifo_get_idx = (pending_fifo_get_idx + 1) % dap->packet_count; +- pending_fifo_block_count--; ++ dap->pending_fifo_get_idx = (dap->pending_fifo_get_idx + 1) % dap->packet_count; ++ dap->pending_fifo_block_count--; + } + + static int cmsis_dap_swd_run_queue(void) + { +- if (pending_fifo_block_count) ++ if (cmsis_dap_handle->pending_fifo_block_count) + cmsis_dap_swd_read_process(cmsis_dap_handle, 0); + + cmsis_dap_swd_write_from_queue(cmsis_dap_handle); + +- while (pending_fifo_block_count) ++ while (cmsis_dap_handle->pending_fifo_block_count) + cmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS); + +- pending_fifo_put_idx = 0; +- pending_fifo_get_idx = 0; ++ cmsis_dap_handle->pending_fifo_put_idx = 0; ++ cmsis_dap_handle->pending_fifo_get_idx = 0; + + int retval = queued_retval; + queued_retval = ERROR_OK; +@@ -934,15 +916,15 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) + { + bool targetsel_cmd = swd_cmd(false, false, DP_TARGETSEL) == cmd; + +- if (pending_fifo[pending_fifo_put_idx].transfer_count == pending_queue_len +- || targetsel_cmd) { +- if (pending_fifo_block_count) ++ if (cmsis_dap_handle->pending_fifo[cmsis_dap_handle->pending_fifo_put_idx].transfer_count == pending_queue_len ++ || targetsel_cmd) { ++ if (cmsis_dap_handle->pending_fifo_block_count) + cmsis_dap_swd_read_process(cmsis_dap_handle, 0); + + /* Not enough room in the queue. Run the queue. */ + cmsis_dap_swd_write_from_queue(cmsis_dap_handle); + +- if (pending_fifo_block_count >= cmsis_dap_handle->packet_count) ++ if (cmsis_dap_handle->pending_fifo_block_count >= cmsis_dap_handle->packet_count) + cmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS); + } + +@@ -954,7 +936,7 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) + return; + } + +- struct pending_request_block *block = &pending_fifo[pending_fifo_put_idx]; ++ struct pending_request_block *block = &cmsis_dap_handle->pending_fifo[cmsis_dap_handle->pending_fifo_put_idx]; + struct pending_transfer_result *transfer = &(block->transfers[block->transfer_count]); + transfer->data = data; + transfer->cmd = cmd; +@@ -1231,17 +1213,18 @@ static int cmsis_dap_init(void) + goto init_err; + + if (data[0] == 1) { /* byte */ +- int pkt_cnt = data[1]; ++ unsigned int pkt_cnt = data[1]; + if (pkt_cnt > 1) + cmsis_dap_handle->packet_count = MIN(MAX_PENDING_REQUESTS, pkt_cnt); + +- LOG_DEBUG("CMSIS-DAP: Packet Count = %d", pkt_cnt); ++ LOG_DEBUG("CMSIS-DAP: Packet Count = %u", pkt_cnt); + } + +- LOG_DEBUG("Allocating FIFO for %d pending packets", cmsis_dap_handle->packet_count); +- for (int i = 0; i < cmsis_dap_handle->packet_count; i++) { +- pending_fifo[i].transfers = malloc(pending_queue_len * sizeof(struct pending_transfer_result)); +- if (!pending_fifo[i].transfers) { ++ LOG_DEBUG("Allocating FIFO for %u pending packets", cmsis_dap_handle->packet_count); ++ for (unsigned int i = 0; i < cmsis_dap_handle->packet_count; i++) { ++ cmsis_dap_handle->pending_fifo[i].transfers = malloc(pending_queue_len ++ * sizeof(struct pending_transfer_result)); ++ if (!cmsis_dap_handle->pending_fifo[i].transfers) { + LOG_ERROR("Unable to allocate memory for CMSIS-DAP queue"); + retval = ERROR_FAIL; + goto init_err; +diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h +index cf929b069..7eaa1f216 100644 +--- a/src/jtag/drivers/cmsis_dap.h ++++ b/src/jtag/drivers/cmsis_dap.h +@@ -7,17 +7,37 @@ + + struct cmsis_dap_backend; + struct cmsis_dap_backend_data; +-struct command_registration; ++ ++struct pending_transfer_result { ++ uint8_t cmd; ++ uint32_t data; ++ void *buffer; ++}; ++ ++/* Up to MIN(packet_count, MAX_PENDING_REQUESTS) requests may be issued ++ * until the first response arrives */ ++#define MAX_PENDING_REQUESTS 4 ++ ++struct pending_request_block { ++ struct pending_transfer_result *transfers; ++ int transfer_count; ++}; + + struct cmsis_dap { + struct cmsis_dap_backend_data *bdata; + const struct cmsis_dap_backend *backend; + uint16_t packet_size; +- int packet_count; + uint8_t *packet_buffer; + uint16_t packet_buffer_size; + uint8_t *command; + uint8_t *response; ++ ++ /* Pending requests are organized as a FIFO - circular buffer */ ++ struct pending_request_block pending_fifo[MAX_PENDING_REQUESTS]; ++ unsigned int packet_count; ++ unsigned int pending_fifo_put_idx, pending_fifo_get_idx; ++ unsigned int pending_fifo_block_count; ++ + uint16_t caps; + uint8_t mode; + uint32_t swo_buf_sz; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0030-jtag-drivers-cmsis_dap-use-dap-parameter-instead-of-.patch b/meta-oe/recipes-devtools/openocd/openocd/0030-jtag-drivers-cmsis_dap-use-dap-parameter-instead-of-.patch new file mode 100644 index 000000000..8c5f74621 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0030-jtag-drivers-cmsis_dap-use-dap-parameter-instead-of-.patch @@ -0,0 +1,68 @@ +From a9b48a6f481344c592e7e05ca06564cdadfe0721 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sat, 19 Nov 2022 07:08:32 +0100 +Subject: [PATCH] jtag/drivers/cmsis_dap: use dap parameter instead of + cmsis_dap_handle + +Replace the direct dereference of cmsis_dap_handle by dereference +of the dap function parameter wherever possible. + +Signed-off-by: Tomas Vanek +Change-Id: I32601dbe0270267642720a8524706aa76d187c3b +Reviewed-on: https://review.openocd.org/c/openocd/+/7361 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/cmsis_dap.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c +index c2f01f33d..49181ad90 100644 +--- a/src/jtag/drivers/cmsis_dap.c ++++ b/src/jtag/drivers/cmsis_dap.c +@@ -290,14 +290,15 @@ static void cmsis_dap_close(struct cmsis_dap *dap) + dap->backend = NULL; + } + +- free(cmsis_dap_handle->packet_buffer); +- free(cmsis_dap_handle); +- cmsis_dap_handle = NULL; ++ free(dap->packet_buffer); + + for (int i = 0; i < MAX_PENDING_REQUESTS; i++) { + free(dap->pending_fifo[i].transfers); + dap->pending_fifo[i].transfers = NULL; + } ++ ++ free(cmsis_dap_handle); ++ cmsis_dap_handle = NULL; + } + + static void cmsis_dap_flush_read(struct cmsis_dap *dap) +@@ -328,7 +329,7 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen) + dap->pending_fifo_get_idx = 0; + } + +- uint8_t current_cmd = cmsis_dap_handle->command[0]; ++ uint8_t current_cmd = dap->command[0]; + int retval = dap->backend->write(dap, txlen, LIBUSB_TIMEOUT_MS); + if (retval < 0) + return retval; +@@ -338,7 +339,7 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen) + if (retval < 0) + return retval; + +- uint8_t *resp = cmsis_dap_handle->response; ++ uint8_t *resp = dap->response; + if (resp[0] == DAP_ERROR) { + LOG_ERROR("CMSIS-DAP command 0x%" PRIx8 " not implemented", current_cmd); + return ERROR_NOT_IMPLEMENTED; +@@ -743,7 +744,7 @@ static int cmsis_dap_cmd_dap_swo_data( + + static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) + { +- uint8_t *command = cmsis_dap_handle->command; ++ uint8_t *command = dap->command; + struct pending_request_block *block = &dap->pending_fifo[dap->pending_fifo_put_idx]; + + LOG_DEBUG_IO("Executing %d queued transactions from FIFO index %u", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0031-jtag-drivers-cmsis_dap-use-unsigned-types.patch b/meta-oe/recipes-devtools/openocd/openocd/0031-jtag-drivers-cmsis_dap-use-unsigned-types.patch new file mode 100644 index 000000000..71d660cf9 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0031-jtag-drivers-cmsis_dap-use-unsigned-types.patch @@ -0,0 +1,179 @@ +From 600d0165cc041a36d3707168aeb113d7a2e6747f Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sat, 19 Nov 2022 07:08:32 +0100 +Subject: [PATCH] jtag/drivers/cmsis_dap: use unsigned types + +Not all variables converted, JTAG part is left as is. + +Signed-off-by: Tomas Vanek +Change-Id: Ie9cc890769a2f53cb3a07fd457030e1b98910d44 +Reviewed-on: https://review.openocd.org/c/openocd/+/7362 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/cmsis_dap.c | 41 ++++++++++++++++++------------------ + src/jtag/drivers/cmsis_dap.h | 6 +++--- + 2 files changed, 24 insertions(+), 23 deletions(-) + +diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c +index 49181ad90..5e01d0647 100644 +--- a/src/jtag/drivers/cmsis_dap.c ++++ b/src/jtag/drivers/cmsis_dap.c +@@ -211,17 +211,17 @@ static const char * const info_caps_str[INFO_CAPS__NUM_CAPS] = { + + struct pending_scan_result { + /** Offset in bytes in the CMD_DAP_JTAG_SEQ response buffer. */ +- unsigned first; ++ unsigned int first; + /** Number of bits to read. */ +- unsigned length; ++ unsigned int length; + /** Location to store the result */ + uint8_t *buffer; + /** Offset in the destination buffer */ +- unsigned buffer_offset; ++ unsigned int buffer_offset; + }; + + /* Each block in FIFO can contain up to pending_queue_len transfers */ +-static int pending_queue_len; ++static unsigned int pending_queue_len; + + /* pointers to buffers that will receive jtag scan results on the next flush */ + #define MAX_PENDING_SCAN_RESULTS 256 +@@ -292,7 +292,7 @@ static void cmsis_dap_close(struct cmsis_dap *dap) + + free(dap->packet_buffer); + +- for (int i = 0; i < MAX_PENDING_REQUESTS; i++) { ++ for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) { + free(dap->pending_fifo[i].transfers); + dap->pending_fifo[i].transfers = NULL; + } +@@ -403,7 +403,7 @@ static int cmsis_dap_cmd_dap_swj_sequence(uint8_t s_len, const uint8_t *sequence + + #ifdef CMSIS_DAP_JTAG_DEBUG + LOG_DEBUG("cmsis-dap TMS sequence: len=%d", s_len); +- for (int i = 0; i < DIV_ROUND_UP(s_len, 8); ++i) ++ for (unsigned int i = 0; i < DIV_ROUND_UP(s_len, 8); ++i) + printf("%02X ", sequence[i]); + + printf("\n"); +@@ -763,7 +763,7 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) + command[2] = block->transfer_count; + size_t idx = 3; + +- for (int i = 0; i < block->transfer_count; i++) { ++ for (unsigned int i = 0; i < block->transfer_count; i++) { + struct pending_transfer_result *transfer = &(block->transfers[i]); + uint8_t cmd = transfer->cmd; + uint32_t data = transfer->data; +@@ -844,7 +844,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms) + goto skip; + } + +- uint8_t transfer_count = resp[1]; ++ unsigned int transfer_count = resp[1]; + uint8_t ack = resp[2] & 0x07; + if (resp[2] & 0x08) { + LOG_DEBUG("CMSIS-DAP Protocol Error @ %d (wrong parity)", transfer_count); +@@ -865,8 +865,8 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms) + + LOG_DEBUG_IO("Received results of %d queued transactions FIFO index %u timeout %i", + transfer_count, dap->pending_fifo_get_idx, timeout_ms); +- size_t idx = 3; +- for (int i = 0; i < transfer_count; i++) { ++ unsigned int idx = 3; ++ for (unsigned int i = 0; i < transfer_count; i++) { + struct pending_transfer_result *transfer = &(block->transfers[i]); + if (transfer->cmd & SWD_CMD_RNW) { + static uint32_t last_read; +@@ -1005,7 +1005,7 @@ static int cmsis_dap_get_caps_info(void) + + cmsis_dap_handle->caps = caps; + +- for (int i = 0; i < INFO_CAPS__NUM_CAPS; ++i) { ++ for (unsigned int i = 0; i < INFO_CAPS__NUM_CAPS; ++i) { + if (caps & BIT(i)) + LOG_INFO("CMSIS-DAP: %s", info_caps_str[i]); + } +@@ -1351,7 +1351,7 @@ static void cmsis_dap_end_state(tap_state_t state) + } + + #ifdef SPRINT_BINARY +-static void sprint_binary(char *s, const uint8_t *buf, int offset, int len) ++static void sprint_binary(char *s, const uint8_t *buf, unsigned int offset, unsigned int len) + { + if (!len) + return; +@@ -1362,7 +1362,7 @@ static void sprint_binary(char *s, const uint8_t *buf, int offset, int len) + buf = { 0xc0 0x18 } offset=3 len=10 should result in: 11000 11000 + i=3 there means i/8 = 0 so c = 0xFF, and + */ +- for (int i = offset; i < offset + len; ++i) { ++ for (unsigned int i = offset; i < offset + len; ++i) { + uint8_t c = buf[i / 8], mask = 1 << (i % 8); + if ((i != offset) && !(i % 8)) + putchar(' '); +@@ -1476,10 +1476,11 @@ static void cmsis_dap_flush(void) + * sequence=NULL means clock out zeros on TDI + * tdo_buffer=NULL means don't capture TDO + */ +-static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int s_offset, +- bool tms, uint8_t *tdo_buffer, int tdo_buffer_offset) ++static void cmsis_dap_add_jtag_sequence(unsigned int s_len, const uint8_t *sequence, ++ unsigned int s_offset, bool tms, ++ uint8_t *tdo_buffer, unsigned int tdo_buffer_offset) + { +- LOG_DEBUG_IO("[at %d] %d bits, tms %s, seq offset %d, tdo buf %p, tdo offset %d", ++ LOG_DEBUG_IO("[at %d] %u bits, tms %s, seq offset %u, tdo buf %p, tdo offset %u", + queued_seq_buf_end, + s_len, tms ? "HIGH" : "LOW", s_offset, tdo_buffer, tdo_buffer_offset); + +@@ -1488,11 +1489,11 @@ static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int + + if (s_len > 64) { + LOG_DEBUG_IO("START JTAG SEQ SPLIT"); +- for (int offset = 0; offset < s_len; offset += 64) { +- int len = s_len - offset; ++ for (unsigned int offset = 0; offset < s_len; offset += 64) { ++ unsigned int len = s_len - offset; + if (len > 64) + len = 64; +- LOG_DEBUG_IO("Splitting long jtag sequence: %d-bit chunk starting at offset %d", len, offset); ++ LOG_DEBUG_IO("Splitting long jtag sequence: %u-bit chunk starting at offset %u", len, offset); + cmsis_dap_add_jtag_sequence( + len, + sequence, +@@ -1506,7 +1507,7 @@ static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int + return; + } + +- int cmd_len = 1 + DIV_ROUND_UP(s_len, 8); ++ unsigned int cmd_len = 1 + DIV_ROUND_UP(s_len, 8); + if (queued_seq_count >= 255 || queued_seq_buf_end + cmd_len > QUEUED_SEQ_BUF_LEN) + /* empty out the buffer */ + cmsis_dap_flush(); +diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h +index 7eaa1f216..80044199b 100644 +--- a/src/jtag/drivers/cmsis_dap.h ++++ b/src/jtag/drivers/cmsis_dap.h +@@ -20,15 +20,15 @@ struct pending_transfer_result { + + struct pending_request_block { + struct pending_transfer_result *transfers; +- int transfer_count; ++ unsigned int transfer_count; + }; + + struct cmsis_dap { + struct cmsis_dap_backend_data *bdata; + const struct cmsis_dap_backend *backend; +- uint16_t packet_size; ++ unsigned int packet_size; ++ unsigned int packet_buffer_size; + uint8_t *packet_buffer; +- uint16_t packet_buffer_size; + uint8_t *command; + uint8_t *response; + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0032-jtag-drivers-cmsis_dap-introduce-packet_usable_size.patch b/meta-oe/recipes-devtools/openocd/openocd/0032-jtag-drivers-cmsis_dap-introduce-packet_usable_size.patch new file mode 100644 index 000000000..f848b75d8 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0032-jtag-drivers-cmsis_dap-introduce-packet_usable_size.patch @@ -0,0 +1,104 @@ +From 3d3d35c9b87243a14b37478f1120c4c8d0a6d0bb Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sat, 19 Nov 2022 07:16:30 +0100 +Subject: [PATCH] jtag/drivers/cmsis_dap: introduce packet_usable_size + +USB bulk backend needs to avoid zero sized USB packets +sent after each full sized packed for performance reasons. + +HID backend uses fixed size HID reports so the full size +of the report can be utilized. + +Introduce packet_usable_size to reflect it. + +Signed-off-by: Tomas Vanek +Change-Id: I34094c9edac5730624480711cbd6aa65883c47c7 +Reviewed-on: https://review.openocd.org/c/openocd/+/7363 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/cmsis_dap.c | 2 +- + src/jtag/drivers/cmsis_dap.h | 1 + + src/jtag/drivers/cmsis_dap_usb_bulk.c | 16 +++++----------- + src/jtag/drivers/cmsis_dap_usb_hid.c | 1 + + 4 files changed, 8 insertions(+), 12 deletions(-) + +diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c +index 5e01d0647..364a17746 100644 +--- a/src/jtag/drivers/cmsis_dap.c ++++ b/src/jtag/drivers/cmsis_dap.c +@@ -229,7 +229,7 @@ static int pending_scan_result_count; + static struct pending_scan_result pending_scan_results[MAX_PENDING_SCAN_RESULTS]; + + /* queued JTAG sequences that will be executed on the next flush */ +-#define QUEUED_SEQ_BUF_LEN (cmsis_dap_handle->packet_size - 3) ++#define QUEUED_SEQ_BUF_LEN (cmsis_dap_handle->packet_usable_size - 3) + static int queued_seq_count; + static int queued_seq_buf_end; + static int queued_seq_tdo_ptr; +diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h +index 80044199b..72e07fb04 100644 +--- a/src/jtag/drivers/cmsis_dap.h ++++ b/src/jtag/drivers/cmsis_dap.h +@@ -27,6 +27,7 @@ struct cmsis_dap { + struct cmsis_dap_backend_data *bdata; + const struct cmsis_dap_backend *backend; + unsigned int packet_size; ++ unsigned int packet_usable_size; + unsigned int packet_buffer_size; + uint8_t *packet_buffer; + uint8_t *command; +diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c +index 55b9a558a..6599c414c 100644 +--- a/src/jtag/drivers/cmsis_dap_usb_bulk.c ++++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c +@@ -352,25 +352,17 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p + return ERROR_FAIL; + } + +- dap->packet_size = packet_size; +- dap->packet_buffer_size = packet_size; + dap->bdata->usb_ctx = ctx; + dap->bdata->dev_handle = dev_handle; + dap->bdata->ep_out = ep_out; + dap->bdata->ep_in = ep_in; + dap->bdata->interface = interface_num; + +- dap->packet_buffer = malloc(dap->packet_buffer_size); +- if (!dap->packet_buffer) { +- LOG_ERROR("unable to allocate memory"); ++ err = cmsis_dap_usb_alloc(dap, packet_size); ++ if (err != ERROR_OK) + cmsis_dap_usb_close(dap); +- return ERROR_FAIL; +- } +- +- dap->command = dap->packet_buffer; +- dap->response = dap->packet_buffer; + +- return ERROR_OK; ++ return err; + } + + libusb_close(dev_handle); +@@ -445,6 +437,8 @@ static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz) + dap->packet_buffer = buf; + dap->packet_size = pkt_sz; + dap->packet_buffer_size = pkt_sz; ++ /* Prevent sending zero size USB packets */ ++ dap->packet_usable_size = pkt_sz - 1; + + dap->command = dap->packet_buffer; + dap->response = dap->packet_buffer; +diff --git a/src/jtag/drivers/cmsis_dap_usb_hid.c b/src/jtag/drivers/cmsis_dap_usb_hid.c +index 592eb0925..52dfd7616 100644 +--- a/src/jtag/drivers/cmsis_dap_usb_hid.c ++++ b/src/jtag/drivers/cmsis_dap_usb_hid.c +@@ -213,6 +213,7 @@ static int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz) + + dap->packet_buffer = buf; + dap->packet_size = pkt_sz; ++ dap->packet_usable_size = pkt_sz; + dap->packet_buffer_size = packet_buffer_size; + + dap->command = dap->packet_buffer + REPORT_ID_SIZE; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0033-jtag-drivers-cmsis_dap-improve-USB-packets-filling.patch b/meta-oe/recipes-devtools/openocd/openocd/0033-jtag-drivers-cmsis_dap-improve-USB-packets-filling.patch new file mode 100644 index 000000000..6fa1aee1a --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0033-jtag-drivers-cmsis_dap-improve-USB-packets-filling.patch @@ -0,0 +1,180 @@ +From 40bac8e8c4e556faaf9c8adc1a030dbc52080fdb Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sat, 19 Nov 2022 07:21:10 +0100 +Subject: [PATCH] jtag/drivers/cmsis_dap: improve USB packets filling + +DAP write transaction occupies 5 bytes of a command packet. +DAP read transaction needs just one byte in a command packet +and expect 4 bytes in a response. + +The fixed maximal number of transactions in a packet caused +packet filling less than optimal. + +Compute both command and expected response sizes based on +read or write direction of each transaction. +Run the queue if one of sizes does not fit into a packet. + +The change increases the speed of the mostly read transfer +from 36 KiB/s to almost 40 KiB/s @ USB FS, adapter speed 1000 +due to reduction of adapter inserted RDBUFF reads. + +Signed-off-by: Tomas Vanek +Change-Id: Ib70812600eaae0403b8ee8673b6f897348496569 +Reviewed-on: https://review.openocd.org/c/openocd/+/7364 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/cmsis_dap.c | 65 +++++++++++++++++++++++++++++++----- + src/jtag/drivers/cmsis_dap.h | 5 +++ + 2 files changed, 62 insertions(+), 8 deletions(-) + +diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c +index 364a17746..10e663862 100644 +--- a/src/jtag/drivers/cmsis_dap.c ++++ b/src/jtag/drivers/cmsis_dap.c +@@ -222,6 +222,8 @@ struct pending_scan_result { + + /* Each block in FIFO can contain up to pending_queue_len transfers */ + static unsigned int pending_queue_len; ++static unsigned int tfer_max_command_size; ++static unsigned int tfer_max_response_size; + + /* pointers to buffers that will receive jtag scan results on the next flush */ + #define MAX_PENDING_SCAN_RESULTS 256 +@@ -742,11 +744,18 @@ static int cmsis_dap_cmd_dap_swo_data( + return ERROR_OK; + } + ++ + static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) + { + uint8_t *command = dap->command; + struct pending_request_block *block = &dap->pending_fifo[dap->pending_fifo_put_idx]; + ++ assert(dap->write_count + dap->read_count == block->transfer_count); ++ ++ /* Reset packet size check counters for the next packet */ ++ dap->write_count = 0; ++ dap->read_count = 0; ++ + LOG_DEBUG_IO("Executing %d queued transactions from FIFO index %u", + block->transfer_count, dap->pending_fifo_put_idx); + +@@ -913,11 +922,43 @@ static int cmsis_dap_swd_run_queue(void) + return retval; + } + ++static unsigned int cmsis_dap_tfer_cmd_size(unsigned int write_count, ++ unsigned int read_count) ++{ ++ unsigned int size = 3; /* header */ ++ size += write_count * (1 + 4); /* DAP register + data */ ++ size += read_count; /* DAP register */ ++ return size; ++} ++ ++static unsigned int cmsis_dap_tfer_resp_size(unsigned int write_count, ++ unsigned int read_count) ++{ ++ unsigned int size = 3; /* header */ ++ size += read_count * 4; /* data */ ++ return size; ++} ++ + static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) + { ++ /* Compute sizes of the DAP Transfer command and the expected response ++ * for all queued and this operation */ + bool targetsel_cmd = swd_cmd(false, false, DP_TARGETSEL) == cmd; + +- if (cmsis_dap_handle->pending_fifo[cmsis_dap_handle->pending_fifo_put_idx].transfer_count == pending_queue_len ++ unsigned int write_count = cmsis_dap_handle->write_count; ++ unsigned int read_count = cmsis_dap_handle->read_count; ++ if (cmd & SWD_CMD_RNW) ++ read_count++; ++ else ++ write_count++; ++ ++ unsigned int cmd_size = cmsis_dap_tfer_cmd_size(write_count, read_count); ++ unsigned int resp_size = cmsis_dap_tfer_resp_size(write_count, read_count); ++ ++ /* Does the DAP Transfer command and the expected response fit into one packet? ++ * Run the queue also before a targetsel - it cannot be queued */ ++ if (cmd_size > tfer_max_command_size ++ || resp_size > tfer_max_response_size + || targetsel_cmd) { + if (cmsis_dap_handle->pending_fifo_block_count) + cmsis_dap_swd_read_process(cmsis_dap_handle, 0); +@@ -929,6 +970,8 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) + cmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS); + } + ++ assert(cmsis_dap_handle->pending_fifo[cmsis_dap_handle->pending_fifo_put_idx].transfer_count < pending_queue_len); ++ + if (queued_retval != ERROR_OK) + return; + +@@ -944,6 +987,9 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) + if (cmd & SWD_CMD_RNW) { + /* Queue a read transaction */ + transfer->buffer = dst; ++ cmsis_dap_handle->read_count++; ++ } else { ++ cmsis_dap_handle->write_count++; + } + block->transfer_count++; + } +@@ -1183,7 +1229,6 @@ static int cmsis_dap_init(void) + /* Be conservative and suppress submitting multiple HID requests + * until we get packet count info from the adaptor */ + cmsis_dap_handle->packet_count = 1; +- pending_queue_len = 12; + + /* INFO_ID_PKT_SZ - short */ + retval = cmsis_dap_cmd_dap_info(INFO_ID_PKT_SZ, &data); +@@ -1193,12 +1238,6 @@ static int cmsis_dap_init(void) + if (data[0] == 2) { /* short */ + uint16_t pkt_sz = data[1] + (data[2] << 8); + if (pkt_sz != cmsis_dap_handle->packet_size) { +- +- /* 4 bytes of command header + 5 bytes per register +- * write. For bulk read sequences just 4 bytes are +- * needed per transfer, so this is suboptimal. */ +- pending_queue_len = (pkt_sz - 4) / 5; +- + free(cmsis_dap_handle->packet_buffer); + retval = cmsis_dap_handle->backend->packet_buffer_alloc(cmsis_dap_handle, pkt_sz); + if (retval != ERROR_OK) +@@ -1208,6 +1247,16 @@ static int cmsis_dap_init(void) + } + } + ++ /* Maximal number of transfers which fit to one packet: ++ * Limited by response size: 3 bytes of response header + 4 per read ++ * Plus writes to full command size: 3 bytes cmd header + 1 per read + 5 per write */ ++ tfer_max_command_size = cmsis_dap_handle->packet_usable_size; ++ tfer_max_response_size = cmsis_dap_handle->packet_usable_size; ++ unsigned int max_reads = tfer_max_response_size / 4; ++ pending_queue_len = max_reads + (tfer_max_command_size - max_reads) / 5; ++ cmsis_dap_handle->write_count = 0; ++ cmsis_dap_handle->read_count = 0; ++ + /* INFO_ID_PKT_CNT - byte */ + retval = cmsis_dap_cmd_dap_info(INFO_ID_PKT_CNT, &data); + if (retval != ERROR_OK) +diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h +index 72e07fb04..1c30975da 100644 +--- a/src/jtag/drivers/cmsis_dap.h ++++ b/src/jtag/drivers/cmsis_dap.h +@@ -33,6 +33,11 @@ struct cmsis_dap { + uint8_t *command; + uint8_t *response; + ++ /* DAP register r/w operation counters used for checking the packet size ++ * that would result from the queue run */ ++ unsigned int write_count; ++ unsigned int read_count; ++ + /* Pending requests are organized as a FIFO - circular buffer */ + struct pending_request_block pending_fifo[MAX_PENDING_REQUESTS]; + unsigned int packet_count; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0034-jtag-drivers-cmsis_dap-speed-up-long-transfers-using.patch b/meta-oe/recipes-devtools/openocd/openocd/0034-jtag-drivers-cmsis_dap-speed-up-long-transfers-using.patch new file mode 100644 index 000000000..f1bba4651 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0034-jtag-drivers-cmsis_dap-speed-up-long-transfers-using.patch @@ -0,0 +1,239 @@ +From 630cb5ea4d65edba42d1c77fa17d9fe78f7b38c2 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Tue, 22 Nov 2022 12:29:52 +0100 +Subject: [PATCH] jtag/drivers/cmsis_dap: speed up long transfers using + DAP_TransferBlock + +DAP_TransferBlock command saves n - 3 bytes in comparison to DAP_Transfer, +where n is number of transfers. + +Use DAP_TransferBlock optionaly to save some USB bandwidth. + +The change increases the speed of the write transfer +from 40 KiB/s to 42 KiB/s @ USB FS, adapter speed 1000. + +Signed-off-by: Tomas Vanek +Change-Id: Ifde0159cfd44481d2b81b90daa088e731c03e26d +Reviewed-on: https://review.openocd.org/c/openocd/+/7372 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/cmsis_dap.c | 96 ++++++++++++++++++++++++++++-------- + src/jtag/drivers/cmsis_dap.h | 9 +++- + 2 files changed, 83 insertions(+), 22 deletions(-) + +diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c +index 10e663862..d2c30cc79 100644 +--- a/src/jtag/drivers/cmsis_dap.c ++++ b/src/jtag/drivers/cmsis_dap.c +@@ -160,6 +160,11 @@ static bool swd_mode; + #define CMD_DAP_TFER_BLOCK 0x06 + #define CMD_DAP_TFER_ABORT 0x07 + ++/* DAP_TransferBlock increases the sum of command/response sizes ++ * (due to 16-bit Transfer Count) if used in a small packet. ++ * Prevent using it until we have at least r/w operations. */ ++#define CMD_DAP_TFER_BLOCK_MIN_OPS 4 ++ + /* DAP Status Code */ + #define DAP_OK 0 + #define DAP_ERROR 0xFF +@@ -756,8 +761,9 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) + dap->write_count = 0; + dap->read_count = 0; + +- LOG_DEBUG_IO("Executing %d queued transactions from FIFO index %u", +- block->transfer_count, dap->pending_fifo_put_idx); ++ LOG_DEBUG_IO("Executing %d queued transactions from FIFO index %u%s", ++ block->transfer_count, dap->pending_fifo_put_idx, ++ cmsis_dap_handle->swd_cmds_differ ? "" : ", same swd ops"); + + if (queued_retval != ERROR_OK) { + LOG_DEBUG("Skipping due to previous errors: %d", queued_retval); +@@ -767,10 +773,21 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) + if (block->transfer_count == 0) + goto skip; + +- command[0] = CMD_DAP_TFER; ++ bool block_cmd = !cmsis_dap_handle->swd_cmds_differ ++ && block->transfer_count >= CMD_DAP_TFER_BLOCK_MIN_OPS; ++ block->command = block_cmd ? CMD_DAP_TFER_BLOCK : CMD_DAP_TFER; ++ ++ command[0] = block->command; + command[1] = 0x00; /* DAP Index */ +- command[2] = block->transfer_count; +- size_t idx = 3; ++ ++ unsigned int idx; ++ if (block_cmd) { ++ h_u16_to_le(&command[2], block->transfer_count); ++ idx = 4; /* The first transfer will store the common DAP register */ ++ } else { ++ command[2] = block->transfer_count; ++ idx = 3; ++ } + + for (unsigned int i = 0; i < block->transfer_count; i++) { + struct pending_transfer_result *transfer = &(block->transfers[i]); +@@ -801,7 +818,9 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) + data &= ~CORUNDETECT; + } + +- command[idx++] = (cmd >> 1) & 0x0f; ++ if (!block_cmd || i == 0) ++ command[idx++] = (cmd >> 1) & 0x0f; ++ + if (!(cmd & SWD_CMD_RNW)) { + h_u32_to_le(&command[idx], data); + idx += 4; +@@ -846,20 +865,28 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms) + } + + uint8_t *resp = dap->response; +- if (resp[0] != CMD_DAP_TFER) { ++ if (resp[0] != block->command) { + LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%x received 0x%" PRIx8, +- CMD_DAP_TFER, resp[0]); ++ block->command, resp[0]); + queued_retval = ERROR_FAIL; + goto skip; + } + +- unsigned int transfer_count = resp[1]; +- uint8_t ack = resp[2] & 0x07; +- if (resp[2] & 0x08) { ++ unsigned int transfer_count; ++ unsigned int idx; ++ if (block->command == CMD_DAP_TFER_BLOCK) { ++ transfer_count = le_to_h_u16(&resp[1]); ++ idx = 3; ++ } else { ++ transfer_count = resp[1]; ++ idx = 2; ++ } ++ if (resp[idx] & 0x08) { + LOG_DEBUG("CMSIS-DAP Protocol Error @ %d (wrong parity)", transfer_count); + queued_retval = ERROR_FAIL; + goto skip; + } ++ uint8_t ack = resp[idx++] & 0x07; + if (ack != SWD_ACK_OK) { + LOG_DEBUG("SWD ack not OK @ %d %s", transfer_count, + ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK"); +@@ -874,7 +901,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms) + + LOG_DEBUG_IO("Received results of %d queued transactions FIFO index %u timeout %i", + transfer_count, dap->pending_fifo_get_idx, timeout_ms); +- unsigned int idx = 3; ++ + for (unsigned int i = 0; i < transfer_count; i++) { + struct pending_transfer_result *transfer = &(block->transfers[i]); + if (transfer->cmd & SWD_CMD_RNW) { +@@ -923,19 +950,30 @@ static int cmsis_dap_swd_run_queue(void) + } + + static unsigned int cmsis_dap_tfer_cmd_size(unsigned int write_count, +- unsigned int read_count) ++ unsigned int read_count, bool block_tfer) + { +- unsigned int size = 3; /* header */ +- size += write_count * (1 + 4); /* DAP register + data */ +- size += read_count; /* DAP register */ ++ unsigned int size; ++ if (block_tfer) { ++ size = 5; /* DAP_TransferBlock header */ ++ size += write_count * 4; /* data */ ++ } else { ++ size = 3; /* DAP_Transfer header */ ++ size += write_count * (1 + 4); /* DAP register + data */ ++ size += read_count; /* DAP register */ ++ } + return size; + } + + static unsigned int cmsis_dap_tfer_resp_size(unsigned int write_count, +- unsigned int read_count) ++ unsigned int read_count, bool block_tfer) + { +- unsigned int size = 3; /* header */ +- size += read_count * 4; /* data */ ++ unsigned int size; ++ if (block_tfer) ++ size = 4; /* DAP_TransferBlock response header */ ++ else ++ size = 3; /* DAP_Transfer response header */ ++ ++ size += read_count * 4; /* data */ + return size; + } + +@@ -947,13 +985,22 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) + + unsigned int write_count = cmsis_dap_handle->write_count; + unsigned int read_count = cmsis_dap_handle->read_count; ++ bool block_cmd; ++ if (write_count + read_count < CMD_DAP_TFER_BLOCK_MIN_OPS) ++ block_cmd = false; ++ else ++ block_cmd = !cmsis_dap_handle->swd_cmds_differ ++ && cmd == cmsis_dap_handle->common_swd_cmd; ++ + if (cmd & SWD_CMD_RNW) + read_count++; + else + write_count++; + +- unsigned int cmd_size = cmsis_dap_tfer_cmd_size(write_count, read_count); +- unsigned int resp_size = cmsis_dap_tfer_resp_size(write_count, read_count); ++ unsigned int cmd_size = cmsis_dap_tfer_cmd_size(write_count, read_count, ++ block_cmd); ++ unsigned int resp_size = cmsis_dap_tfer_resp_size(write_count, read_count, ++ block_cmd); + + /* Does the DAP Transfer command and the expected response fit into one packet? + * Run the queue also before a targetsel - it cannot be queued */ +@@ -984,6 +1031,13 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) + struct pending_transfer_result *transfer = &(block->transfers[block->transfer_count]); + transfer->data = data; + transfer->cmd = cmd; ++ if (block->transfer_count == 0) { ++ cmsis_dap_handle->swd_cmds_differ = false; ++ cmsis_dap_handle->common_swd_cmd = cmd; ++ } else if (cmd != cmsis_dap_handle->common_swd_cmd) { ++ cmsis_dap_handle->swd_cmds_differ = true; ++ } ++ + if (cmd & SWD_CMD_RNW) { + /* Queue a read transaction */ + transfer->buffer = dst; +diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h +index 1c30975da..16885a51d 100644 +--- a/src/jtag/drivers/cmsis_dap.h ++++ b/src/jtag/drivers/cmsis_dap.h +@@ -21,6 +21,7 @@ struct pending_transfer_result { + struct pending_request_block { + struct pending_transfer_result *transfers; + unsigned int transfer_count; ++ uint8_t command; + }; + + struct cmsis_dap { +@@ -33,11 +34,17 @@ struct cmsis_dap { + uint8_t *command; + uint8_t *response; + +- /* DAP register r/w operation counters used for checking the packet size ++ /* DP/AP register r/w operation counters used for checking the packet size + * that would result from the queue run */ + unsigned int write_count; + unsigned int read_count; + ++ /* We can use DAP_TransferBlock only if all SWD operations in the packet ++ * are either all writes or all reads and use the same DP/AP register. ++ * The following variables keep track of it */ ++ uint8_t common_swd_cmd; ++ bool swd_cmds_differ; ++ + /* Pending requests are organized as a FIFO - circular buffer */ + struct pending_request_block pending_fifo[MAX_PENDING_REQUESTS]; + unsigned int packet_count; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0035-jtag-drivers-cmsis_dap-prevent-conn-discon-workaroun.patch b/meta-oe/recipes-devtools/openocd/openocd/0035-jtag-drivers-cmsis_dap-prevent-conn-discon-workaroun.patch new file mode 100644 index 000000000..b2ce3b27b --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0035-jtag-drivers-cmsis_dap-prevent-conn-discon-workaroun.patch @@ -0,0 +1,34 @@ +From 5292c7eae925d59d6b6c0017b6a4995d39a6e9ee Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Thu, 24 Nov 2022 14:21:59 +0100 +Subject: [PATCH] jtag/drivers/cmsis_dap: prevent conn/discon workaround before + line reset + +The line reset SWD sequence is used quite often in SWD multidrop mode. +Prevent the ugly connect/disconnect adapter firmware bug workaround +to be called before each line reset. + +Signed-off-by: Tomas Vanek +Change-Id: Id85bff075dba9077e4e501e2cdcfd64d5d9d0531 +Reviewed-on: https://review.openocd.org/c/openocd/+/7381 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/cmsis_dap.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c +index d2c30cc79..0c42a7f1e 100644 +--- a/src/jtag/drivers/cmsis_dap.c ++++ b/src/jtag/drivers/cmsis_dap.c +@@ -1158,7 +1158,9 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq) + unsigned int s_len; + int retval; + +- if ((output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST)) == (SWJ_PIN_SRST | SWJ_PIN_TRST)) { ++ if (seq != LINE_RESET && ++ (output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST)) ++ == (SWJ_PIN_SRST | SWJ_PIN_TRST)) { + /* Following workaround deasserts reset on most adapters. + * Do not reconnect if a reset line is active! + * Reconnecting would break connecting under reset. */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0036-tcl-target-enable-rtos-hwthread.patch b/meta-oe/recipes-devtools/openocd/openocd/0036-tcl-target-enable-rtos-hwthread.patch new file mode 100644 index 000000000..4537346c3 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0036-tcl-target-enable-rtos-hwthread.patch @@ -0,0 +1,84 @@ +From a3ed12401b1f7d9578fb7da881d3504e07acfc27 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Tue, 29 Nov 2022 00:34:44 +0100 +Subject: [PATCH] tcl/target: enable -rtos hwthread + +The rtos hwthread has been merged in 2019 with commit 85ba2dc4c6ab +("rtos/hwthread: add hardware-thread pseudo rtos"). +During review in patchset 19 the name of the rtos has been changed +from 'hawt' to 'hwthread'. + +Some target config file was already merged ready for hwthread, but +keeping the relevant lines commented and still reporting the old +name. + +Enable rtos hwtread to the target that were supposed to use it. +Fix the name of the rtos. + +Change-Id: I877862dcdba39f26462bb542bac06d1a5f5f222d +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7384 +Tested-by: jenkins +--- + tcl/target/hi3798.cfg | 3 +-- + tcl/target/hi6220.cfg | 3 +-- + tcl/target/marvell/88f37x0.cfg | 3 +-- + tcl/target/xilinx_zynqmp.cfg | 3 +-- + 4 files changed, 4 insertions(+), 8 deletions(-) + +diff --git a/tcl/target/hi3798.cfg b/tcl/target/hi3798.cfg +index 4373962e4..722305dcf 100644 +--- a/tcl/target/hi3798.cfg ++++ b/tcl/target/hi3798.cfg +@@ -42,8 +42,7 @@ for { set _core 0 } { $_core < $_cores } { incr _core 1 } { + #set _command "$_command -defer-examine" + set _smp_command "$_smp_command ${_TARGETNAME}$_core" + } else { +- # uncomment when "hawt" rtos is merged +- # set _command "$_command -rtos hawt" ++ set _command "$_command -rtos hwthread" + set _smp_command "target smp ${_TARGETNAME}$_core" + } + +diff --git a/tcl/target/hi6220.cfg b/tcl/target/hi6220.cfg +index f5f7fc9a4..5b0389925 100644 +--- a/tcl/target/hi6220.cfg ++++ b/tcl/target/hi6220.cfg +@@ -49,8 +49,7 @@ for { set _core 0 } { $_core < $_cores } { incr _core 1 } { + set _command "$_command -defer-examine" + set _smp_command "$_smp_command ${_TARGETNAME}$_core" + } else { +- # uncomment when "hawt" rtos is merged +- # set _command "$_command -rtos hawt" ++ set _command "$_command -rtos hwthread" + set _smp_command "target smp ${_TARGETNAME}$_core" + } + +diff --git a/tcl/target/marvell/88f37x0.cfg b/tcl/target/marvell/88f37x0.cfg +index d80f4ef6f..738d22110 100644 +--- a/tcl/target/marvell/88f37x0.cfg ++++ b/tcl/target/marvell/88f37x0.cfg +@@ -57,8 +57,7 @@ for { set _core 0 } { $_core < $_cores } { incr _core 1 } { + set _command "$_command -defer-examine" + set _smp_command "$_smp_command ${_TARGETNAME}$_core" + } else { +- # uncomment when "hawt" rtos is merged +- # set _command "$_command -rtos hawt" ++ set _command "$_command -rtos hwthread" + set _smp_command "target smp ${_TARGETNAME}$_core" + } + +diff --git a/tcl/target/xilinx_zynqmp.cfg b/tcl/target/xilinx_zynqmp.cfg +index 893372978..9734a1837 100644 +--- a/tcl/target/xilinx_zynqmp.cfg ++++ b/tcl/target/xilinx_zynqmp.cfg +@@ -86,8 +86,7 @@ for { set _core 0 } { $_core < $_cores } { incr _core } { + set _command "$_command -defer-examine" + set _smp_command "$_smp_command $_TARGETNAME.$_core" + } else { +- # uncomment when "hawt" rtos is merged +- #set _command "$_command -rtos hawt" ++ set _command "$_command -rtos hwthread" + set _smp_command "target smp $_TARGETNAME.$_core" + } + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0037-flash-nor-stm32l4x-Add-revision-X-and-C-for-STM32U57.patch b/meta-oe/recipes-devtools/openocd/openocd/0037-flash-nor-stm32l4x-Add-revision-X-and-C-for-STM32U57.patch new file mode 100644 index 000000000..251c39da3 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0037-flash-nor-stm32l4x-Add-revision-X-and-C-for-STM32U57.patch @@ -0,0 +1,27 @@ +From dbb42ca18d471b6bffddbd441b1da2ffe18d7400 Mon Sep 17 00:00:00 2001 +From: Marc Schink +Date: Wed, 7 Dec 2022 13:13:04 +0100 +Subject: [PATCH] flash/nor/stm32l4x: Add revision 'X' and 'C' for + STM32U575/585 devices + +Change-Id: I4d950dc0a1421036418f2e5c1f0ed8eca86efc1a +Signed-off-by: Marc Schink +Reviewed-on: https://review.openocd.org/c/openocd/+/7390 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/stm32l4x.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c +index 92d511c17..c67dbf75d 100644 +--- a/src/flash/nor/stm32l4x.c ++++ b/src/flash/nor/stm32l4x.c +@@ -327,6 +327,7 @@ static const struct stm32l4_rev stm32g49_g4axx_revs[] = { + + static const struct stm32l4_rev stm32u57_u58xx_revs[] = { + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2000, "B" }, ++ { 0x2001, "X" }, { 0x3000, "C" }, + }; + + static const struct stm32l4_rev stm32wb1xx_revs[] = { diff --git a/meta-oe/recipes-devtools/openocd/openocd/0038-.gitignore-Add-.cache-and-compile_commands.json.patch b/meta-oe/recipes-devtools/openocd/openocd/0038-.gitignore-Add-.cache-and-compile_commands.json.patch new file mode 100644 index 000000000..a912e5b04 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0038-.gitignore-Add-.cache-and-compile_commands.json.patch @@ -0,0 +1,43 @@ +From 69571354f4741f791a4a70c68ca082f765f98c88 Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Wed, 21 Dec 2022 11:00:53 +0100 +Subject: [PATCH] .gitignore: Add .cache and compile_commands.json + +Enhancing the editor / IDE experience with the use of the language +server protocol (lsp) is getting more and more common. The most widely +used lsp implementation for C/C++ outside of Redmond is clangd. + +Clangd uses compile_commands.json, that contains the compiler invocation +for each compilation unit, to get the required $CFLAGS to successfully +located header files etc. This is best automatically generated from with +bear on Makefile based build systems. Hence, there is little value in +adding it to the git repo. + +In addition, clangd generates cache files in the .cache folder. Again, +there is no reason in tracking it with git. + +Change-Id: Ic5165d10aca3a1cc9e9398af9dd2fbf0977608b3 +Signed-off-by: Marian Buschsieweke +Reviewed-on: https://review.openocd.org/c/openocd/+/7414 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + .gitignore | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/.gitignore b/.gitignore +index 818bb0cd3..103dad2c7 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -103,3 +103,11 @@ GTAGS + + # checkpatch script files + .checkpatch-camelcase.* ++ ++# clangd (e.g. for advanced code completion and linting) generates cache files ++# into .cache ++.cache ++ ++# A compile_commands.json can be generated using bear and will help tools such ++# as clangd to locate header files and use correct $CFLAGS ++compile_commands.json diff --git a/meta-oe/recipes-devtools/openocd/openocd/0039-jtag-parse-command-options-in-swd-newdap.patch b/meta-oe/recipes-devtools/openocd/openocd/0039-jtag-parse-command-options-in-swd-newdap.patch new file mode 100644 index 000000000..bc449bd7c --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0039-jtag-parse-command-options-in-swd-newdap.patch @@ -0,0 +1,49 @@ +From 7a890a8f256f28b1c8b0dde3b62ab81c7c139d55 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 1 Jan 2023 18:26:53 +0100 +Subject: [PATCH] jtag: parse command options in 'swd newdap' + +The same code is currently used for commands 'jtag newtap' and +'swd newdap' (plus dapdirect versions), but for SWD case the code +skips the parsing of the command line as not every flag is used. +This has the drawback that syntax errors get unchecked. + +Move the check about the transport so the command line get always +parsed even when the corresponding flags are not useful. + +Change-Id: I596c3beb04e9e8a9ebe6ee68a61395b679d43b3e +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7427 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/jtag/tcl.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c +index b1815b79d..fc0d562e2 100644 +--- a/src/jtag/tcl.c ++++ b/src/jtag/tcl.c +@@ -557,13 +557,6 @@ static int jim_newtap_cmd(struct jim_getopt_info *goi) + LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", + tap->chip, tap->tapname, tap->dotted_name, goi->argc); + +- if (!transport_is_jtag()) { +- /* SWD doesn't require any JTAG tap parameters */ +- tap->enabled = true; +- jtag_tap_init(tap); +- return JIM_OK; +- } +- + /* IEEE specifies that the two LSBs of an IR scan are 01, so make + * that the default. The "-ircapture" and "-irmask" options are only + * needed to cope with nonstandard TAPs, or to specify more bits. +@@ -618,7 +611,7 @@ static int jim_newtap_cmd(struct jim_getopt_info *goi) + tap->enabled = !tap->disabled_after_reset; + + /* Did all the required option bits get cleared? */ +- if (tap->ir_length != 0) { ++ if (!transport_is_jtag() || tap->ir_length != 0) { + jtag_tap_init(tap); + return JIM_OK; + } diff --git a/meta-oe/recipes-devtools/openocd/openocd/0040-jtag-hla-use-generic-helper-for-commands-jtag-newtap.patch b/meta-oe/recipes-devtools/openocd/openocd/0040-jtag-hla-use-generic-helper-for-commands-jtag-newtap.patch new file mode 100644 index 000000000..a9f75aeeb --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0040-jtag-hla-use-generic-helper-for-commands-jtag-newtap.patch @@ -0,0 +1,270 @@ +From cda39f929e65316478f2f41f461b0cbb3338806c Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 1 Jan 2023 19:17:18 +0100 +Subject: [PATCH] jtag: hla: use generic helper for commands 'jtag newtap' 'swd + newdap' + +The commands 'jtag newtap' and 'swd newdap' have to work either on +HLA transport and on standard JTAG/SWD. Having a dedicated +implementation for HLA is a non-sense. + +Reuse the generic code jim_jtag_newtap() and drop the files +hla_tcl.[ch] as they are now empty. + +Change-Id: I9dabbdc2a6f338f23b2fd3ed1a4dc3da0200c080 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7428 +Tested-by: jenkins +--- + src/jtag/hla/Makefile.am | 4 +- + src/jtag/hla/hla_interface.c | 1 - + src/jtag/hla/hla_layout.c | 1 - + src/jtag/hla/hla_tcl.c | 143 ----------------------------------- + src/jtag/hla/hla_tcl.h | 17 ----- + src/jtag/hla/hla_transport.c | 5 +- + 6 files changed, 3 insertions(+), 168 deletions(-) + delete mode 100644 src/jtag/hla/hla_tcl.c + delete mode 100644 src/jtag/hla/hla_tcl.h + +diff --git a/src/jtag/hla/Makefile.am b/src/jtag/hla/Makefile.am +index 41117868a..ea6e11dd6 100644 +--- a/src/jtag/hla/Makefile.am ++++ b/src/jtag/hla/Makefile.am +@@ -4,10 +4,8 @@ noinst_LTLIBRARIES += %D%/libocdhla.la + + %C%_libocdhla_la_SOURCES = \ + %D%/hla_transport.c \ +- %D%/hla_tcl.c \ + %D%/hla_interface.c \ + %D%/hla_layout.c \ + %D%/hla_transport.h \ + %D%/hla_interface.h \ +- %D%/hla_layout.h \ +- %D%/hla_tcl.h ++ %D%/hla_layout.h +diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c +index 6198b3db4..f4bfeb1a1 100644 +--- a/src/jtag/hla/hla_interface.c ++++ b/src/jtag/hla/hla_interface.c +@@ -17,7 +17,6 @@ + #include + #include + +-#include + #include + #include + #include +diff --git a/src/jtag/hla/hla_layout.c b/src/jtag/hla/hla_layout.c +index a760f0b3c..51671d60a 100644 +--- a/src/jtag/hla/hla_layout.c ++++ b/src/jtag/hla/hla_layout.c +@@ -18,7 +18,6 @@ + #include + + #include +-#include + #include + #include + +diff --git a/src/jtag/hla/hla_tcl.c b/src/jtag/hla/hla_tcl.c +deleted file mode 100644 +index 328339955..000000000 +--- a/src/jtag/hla/hla_tcl.c ++++ /dev/null +@@ -1,143 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-or-later +- +-/*************************************************************************** +- * Copyright (C) 2011 by Mathias Kuester * +- * Mathias Kuester * +- * * +- * Copyright (C) 2012 by Spencer Oliver * +- * spen@spen-soft.co.uk * +- ***************************************************************************/ +- +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-/* project specific includes */ +-#include +-#include +-#include +- +-static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi, +- struct jtag_tap *tap) +-{ +- jim_wide w; +- int e = jim_getopt_wide(goi, &w); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", +- n->name); +- return e; +- } +- +- uint32_t *p = realloc(tap->expected_ids, +- (tap->expected_ids_cnt + 1) * sizeof(uint32_t)); +- if (!p) { +- Jim_SetResultFormatted(goi->interp, "no memory"); +- return JIM_ERR; +- } +- +- tap->expected_ids = p; +- tap->expected_ids[tap->expected_ids_cnt++] = w; +- +- return JIM_OK; +-} +- +-#define NTAP_OPT_IRLEN 0 +-#define NTAP_OPT_IRMASK 1 +-#define NTAP_OPT_IRCAPTURE 2 +-#define NTAP_OPT_ENABLED 3 +-#define NTAP_OPT_DISABLED 4 +-#define NTAP_OPT_EXPECTED_ID 5 +-#define NTAP_OPT_VERSION 6 +-#define NTAP_OPT_BYPASS 7 +- +-static int jim_hl_newtap_cmd(struct jim_getopt_info *goi) +-{ +- struct jtag_tap *tap; +- int x; +- int e; +- struct jim_nvp *n; +- char *cp; +- const struct jim_nvp opts[] = { +- { .name = "-irlen", .value = NTAP_OPT_IRLEN }, +- { .name = "-irmask", .value = NTAP_OPT_IRMASK }, +- { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE }, +- { .name = "-enable", .value = NTAP_OPT_ENABLED }, +- { .name = "-disable", .value = NTAP_OPT_DISABLED }, +- { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID }, +- { .name = "-ignore-version", .value = NTAP_OPT_VERSION }, +- { .name = "-ignore-bypass", .value = NTAP_OPT_BYPASS }, +- { .name = NULL, .value = -1}, +- }; +- +- tap = calloc(1, sizeof(struct jtag_tap)); +- if (!tap) { +- Jim_SetResultFormatted(goi->interp, "no memory"); +- return JIM_ERR; +- } +- +- /* +- * we expect CHIP + TAP + OPTIONS +- * */ +- if (goi->argc < 3) { +- Jim_SetResultFormatted(goi->interp, +- "Missing CHIP TAP OPTIONS ...."); +- free(tap); +- return JIM_ERR; +- } +- +- const char *tmp; +- jim_getopt_string(goi, &tmp, NULL); +- tap->chip = strdup(tmp); +- +- jim_getopt_string(goi, &tmp, NULL); +- tap->tapname = strdup(tmp); +- +- /* name + dot + name + null */ +- x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1; +- cp = malloc(x); +- sprintf(cp, "%s.%s", tap->chip, tap->tapname); +- tap->dotted_name = cp; +- +- LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", +- tap->chip, tap->tapname, tap->dotted_name, goi->argc); +- +- while (goi->argc) { +- e = jim_getopt_nvp(goi, opts, &n); +- if (e != JIM_OK) { +- jim_getopt_nvp_unknown(goi, opts, 0); +- free(cp); +- free(tap); +- return e; +- } +- LOG_DEBUG("Processing option: %s", n->name); +- switch (n->value) { +- case NTAP_OPT_EXPECTED_ID: +- e = jim_newtap_expected_id(n, goi, tap); +- if (e != JIM_OK) { +- free(cp); +- free(tap); +- return e; +- } +- break; +- case NTAP_OPT_IRLEN: +- case NTAP_OPT_IRMASK: +- case NTAP_OPT_IRCAPTURE: +- /* dummy read to ignore the next argument */ +- jim_getopt_wide(goi, NULL); +- break; +- } /* switch (n->value) */ +- } /* while (goi->argc) */ +- +- /* default is enabled-after-reset */ +- tap->enabled = !tap->disabled_after_reset; +- +- jtag_tap_init(tap); +- return JIM_OK; +-} +- +-int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +-{ +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- return jim_hl_newtap_cmd(&goi); +-} +diff --git a/src/jtag/hla/hla_tcl.h b/src/jtag/hla/hla_tcl.h +deleted file mode 100644 +index b028e4b50..000000000 +--- a/src/jtag/hla/hla_tcl.h ++++ /dev/null +@@ -1,17 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright (C) 2011 by Mathias Kuester * +- * Mathias Kuester * +- * * +- * Copyright (C) 2012 by Spencer Oliver * +- * spen@spen-soft.co.uk * +- ***************************************************************************/ +- +-#ifndef OPENOCD_JTAG_HLA_HLA_TCL_H +-#define OPENOCD_JTAG_HLA_HLA_TCL_H +- +-/** */ +-int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv); +- +-#endif /* OPENOCD_JTAG_HLA_HLA_TCL_H */ +diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c +index 91228bed2..004e9f0c5 100644 +--- a/src/jtag/hla/hla_transport.c ++++ b/src/jtag/hla/hla_transport.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -38,7 +37,7 @@ static const struct command_registration hl_swd_transport_subcommand_handlers[] + { + .name = "newdap", + .mode = COMMAND_CONFIG, +- .jim_handler = jim_hl_newtap, ++ .jim_handler = jim_jtag_newtap, + .help = "declare a new SWD DAP", + }, + COMMAND_REGISTRATION_DONE +@@ -59,7 +58,7 @@ static const struct command_registration hl_transport_jtag_subcommand_handlers[] + { + .name = "newtap", + .mode = COMMAND_CONFIG, +- .jim_handler = jim_hl_newtap, ++ .jim_handler = jim_jtag_newtap, + .help = "Create a new TAP instance named basename.tap_type, " + "and appends it to the scan chain.", + .usage = "basename tap_type '-irlen' count " diff --git a/meta-oe/recipes-devtools/openocd/openocd/0041-flash-nor-psoc4-drop-jtag_poll_mask-from-flash-write.patch b/meta-oe/recipes-devtools/openocd/openocd/0041-flash-nor-psoc4-drop-jtag_poll_mask-from-flash-write.patch new file mode 100644 index 000000000..64f1b07c1 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0041-flash-nor-psoc4-drop-jtag_poll_mask-from-flash-write.patch @@ -0,0 +1,40 @@ +From 92dd917f5a2af4470b151adc3492f9b3c68caaa9 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sun, 4 Sep 2022 14:18:26 +0200 +Subject: [PATCH] flash/nor/psoc4: drop jtag_poll_mask() from flash write + +Polling the target makes no harm during PSoC 4 flash write in the current +OpenOCD code. Don't mask it. + +Change-Id: I6625ded0162ee3a96b92188844d0d2d6c30101c2 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7162 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/psoc4.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c +index c935bd5f2..fb462c1e5 100644 +--- a/src/flash/nor/psoc4.c ++++ b/src/flash/nor/psoc4.c +@@ -651,9 +651,6 @@ static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer, + if (row_offset) + memset(row_buffer, bank->default_padded_value, row_offset); + +- /* Mask automatic polling triggered by execution of halted events */ +- bool save_poll_mask = jtag_poll_mask(); +- + while (count) { + uint32_t chunk_size = psoc4_info->row_size - row_offset; + if (chunk_size > count) { +@@ -693,8 +690,6 @@ static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer, + } + + cleanup: +- jtag_poll_unmask(save_poll_mask); +- + free(sysrq_buffer); + return retval; + } diff --git a/meta-oe/recipes-devtools/openocd/openocd/0042-helper-Add-generic-little-endian-CRC32-function.patch b/meta-oe/recipes-devtools/openocd/openocd/0042-helper-Add-generic-little-endian-CRC32-function.patch new file mode 100644 index 000000000..6a234984e --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0042-helper-Add-generic-little-endian-CRC32-function.patch @@ -0,0 +1,216 @@ +From 6e67f1473af15adc7c4052cee27ad84883b286d4 Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Thu, 22 Dec 2022 13:20:07 +0100 +Subject: [PATCH] helper: Add generic little endian CRC32 function + +This generalizes the little endian CRC32 function used in the OR1K +target and moves it to a common helper, so that other places do not need +to reinvent the wheel. It is directly used in the OR1K target. + +Change-Id: I0e55340281a5bfd80669bb1994f3a96fecc1248a +Signed-off-by: Marian Buschsieweke +Reviewed-on: https://review.openocd.org/c/openocd/+/7415 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/helper/Makefile.am | 2 ++ + src/helper/crc32.c | 50 +++++++++++++++++++++++++++++++ + src/helper/crc32.h | 37 +++++++++++++++++++++++ + src/target/openrisc/or1k_du_adv.c | 34 ++++----------------- + 4 files changed, 95 insertions(+), 28 deletions(-) + create mode 100644 src/helper/crc32.c + create mode 100644 src/helper/crc32.h + +diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am +index 7354f5422..c4c60d96b 100644 +--- a/src/helper/Makefile.am ++++ b/src/helper/Makefile.am +@@ -9,6 +9,7 @@ noinst_LTLIBRARIES += %D%/libhelper.la + %D%/configuration.c \ + %D%/log.c \ + %D%/command.c \ ++ %D%/crc32.c \ + %D%/time_support.c \ + %D%/replacements.c \ + %D%/fileio.c \ +@@ -24,6 +25,7 @@ noinst_LTLIBRARIES += %D%/libhelper.la + %D%/types.h \ + %D%/log.h \ + %D%/command.h \ ++ %D%/crc32.h \ + %D%/time_support.h \ + %D%/replacements.h \ + %D%/fileio.h \ +diff --git a/src/helper/crc32.c b/src/helper/crc32.c +new file mode 100644 +index 000000000..441a46c57 +--- /dev/null ++++ b/src/helper/crc32.c +@@ -0,0 +1,50 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++/*************************************************************************** ++ * Copyright (C) 2013-2014 by Franck Jullien * ++ * elec4fun@gmail.com * ++ * * ++ * Copyright (C) 2022 Otto-von-Guericke-Universität Magdeburg * ++ * marian.buschsieweke@ovgu.de * ++ ***************************************************************************/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "crc32.h" ++#include ++#include ++ ++static uint32_t crc_le_step(uint32_t poly, uint32_t crc, uint32_t data_in, ++ unsigned int data_bits) ++{ ++ for (unsigned int i = 0; i < data_bits; i++) { ++ uint32_t d, c; ++ d = ((data_in >> i) & 0x1) ? 0xffffffff : 0; ++ c = (crc & 0x1) ? 0xffffffff : 0; ++ crc = crc >> 1; ++ crc = crc ^ ((d ^ c) & poly); ++ } ++ ++ return crc; ++} ++ ++uint32_t crc32_le(uint32_t poly, uint32_t seed, const void *_data, ++ size_t data_len) ++{ ++ if (((uintptr_t)_data & 0x3) || (data_len & 0x3)) { ++ /* data is unaligned, processing data one byte at a time */ ++ const uint8_t *data = _data; ++ for (size_t i = 0; i < data_len; i++) ++ seed = crc_le_step(poly, seed, data[i], 8); ++ } else { ++ /* data is aligned, processing 32 bit at a time */ ++ data_len >>= 2; ++ const uint32_t *data = _data; ++ for (size_t i = 0; i < data_len; i++) ++ seed = crc_le_step(poly, seed, data[i], 32); ++ } ++ ++ return seed; ++} +diff --git a/src/helper/crc32.h b/src/helper/crc32.h +new file mode 100644 +index 000000000..8f077863a +--- /dev/null ++++ b/src/helper/crc32.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++/*************************************************************************** ++ * Copyright (C) 2022 Otto-von-Guericke-Universität Magdeburg * ++ * marian.buschsieweke@ovgu.de * ++ ***************************************************************************/ ++ ++#ifndef OPENOCD_HELPER_CRC32_H ++#define OPENOCD_HELPER_CRC32_H ++ ++#include ++#include ++ ++/** @file ++ * A generic CRC32 implementation ++ */ ++ ++/** ++ * CRC32 polynomial commonly used for little endian CRC32 ++ */ ++#define CRC32_POLY_LE 0xedb88320 ++ ++/** ++ * Calculate the CRC32 value of the given data ++ * @param poly The polynomial of the CRC ++ * @param seed The seed to use (mostly either `0` or `0xffffffff`) ++ * @param data The data to calculate the CRC32 of ++ * @param data_len The length of the data in @p data in bytes ++ * @return The CRC value of the first @p data_len bytes at @p data ++ * @note This function can be used to incrementally compute the CRC one ++ * chunk of data at a time by using the CRC32 of the previous chunk ++ * as @p seed for the next chunk. ++ */ ++uint32_t crc32_le(uint32_t poly, uint32_t seed, const void *data, ++ size_t data_len); ++ ++#endif /* OPENOCD_HELPER_CRC32_H */ +diff --git a/src/target/openrisc/or1k_du_adv.c b/src/target/openrisc/or1k_du_adv.c +index e4c89e5b5..e4003a213 100644 +--- a/src/target/openrisc/or1k_du_adv.c ++++ b/src/target/openrisc/or1k_du_adv.c +@@ -22,8 +22,9 @@ + #include "or1k_du.h" + #include "jsp_server.h" + +-#include ++#include + #include ++#include + + #define JSP_BANNER "\n\r" \ + "******************************\n\r" \ +@@ -67,13 +68,6 @@ + #define DBG_CPU_CR_STALL 0x01 + #define DBG_CPU_CR_RESET 0x02 + +-/* Polynomial for the CRC calculation +- * Yes, it's backwards. Yes, this is on purpose. +- * The hardware is designed this way to save on logic and routing, +- * and it's really all the same to us here. +- */ +-#define ADBG_CRC_POLY 0xedb88320 +- + /* These are for the internal registers in the Wishbone module + * The first is the length of the index register, + * the indexes of the various registers are defined after that. +@@ -133,20 +127,6 @@ static struct or1k_du or1k_du_adv; + + static const char * const chain_name[] = {"WISHBONE", "CPU0", "CPU1", "JSP"}; + +-static uint32_t adbg_compute_crc(uint32_t crc, uint32_t data_in, +- int length_bits) +-{ +- for (int i = 0; i < length_bits; i++) { +- uint32_t d, c; +- d = ((data_in >> i) & 0x1) ? 0xffffffff : 0; +- c = (crc & 0x1) ? 0xffffffff : 0; +- crc = crc >> 1; +- crc = crc ^ ((d ^ c) & ADBG_CRC_POLY); +- } +- +- return crc; +-} +- + static int find_status_bit(void *_buf, int len) + { + int i = 0; +@@ -522,9 +502,8 @@ retry_read_full: + memcpy(data, in_buffer, total_size_bytes); + memcpy(&crc_read, &in_buffer[total_size_bytes], 4); + +- uint32_t crc_calc = 0xffffffff; +- for (int i = 0; i < total_size_bytes; i++) +- crc_calc = adbg_compute_crc(crc_calc, data[i], 8); ++ uint32_t crc_calc = crc32_le(CRC32_POLY_LE, 0xffffffff, data, ++ total_size_bytes); + + if (crc_calc != crc_read) { + LOG_WARNING("CRC ERROR! Computed 0x%08" PRIx32 ", read CRC 0x%08" PRIx32, crc_calc, crc_read); +@@ -650,9 +629,8 @@ retry_full_write: + field[0].out_value = &value; + field[0].in_value = NULL; + +- uint32_t crc_calc = 0xffffffff; +- for (int i = 0; i < (count * size); i++) +- crc_calc = adbg_compute_crc(crc_calc, data[i], 8); ++ uint32_t crc_calc = crc32_le(CRC32_POLY_LE, 0xffffffff, data, ++ count * size); + + field[1].num_bits = count * size * 8; + field[1].out_value = data; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0043-stm32f3x-Allow-overriding-the-flash-bank-size.patch b/meta-oe/recipes-devtools/openocd/openocd/0043-stm32f3x-Allow-overriding-the-flash-bank-size.patch new file mode 100644 index 000000000..d6a4bcbf1 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0043-stm32f3x-Allow-overriding-the-flash-bank-size.patch @@ -0,0 +1,44 @@ +From bc3c07b1768df878d04aa7cc8e9187e90cd93821 Mon Sep 17 00:00:00 2001 +From: Andreas Fritiofson +Date: Wed, 18 Jan 2023 09:23:32 +0100 +Subject: [PATCH] stm32f3x: Allow overriding the flash bank size + +Same mechanism as in stm32f1x.cfg reused here. + +Change-Id: I81f02feb2b655e8259341b22180f3a8b82e28d05 +Signed-off-by: Andreas Fritiofson +Reviewed-on: https://review.openocd.org/c/openocd/+/7438 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + tcl/target/stm32f3x.cfg | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/tcl/target/stm32f3x.cfg b/tcl/target/stm32f3x.cfg +index 4ecc7eda3..aa978d9c8 100644 +--- a/tcl/target/stm32f3x.cfg ++++ b/tcl/target/stm32f3x.cfg +@@ -24,6 +24,14 @@ if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE 0x4000 + } + ++# Allow overriding the Flash bank size ++if { [info exists FLASH_SIZE] } { ++ set _FLASH_SIZE $FLASH_SIZE ++} else { ++ # autodetect size ++ set _FLASH_SIZE 0 ++} ++ + # JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz + # + # Since we may be running of an RC oscilator, we crank down the speed a +@@ -63,7 +71,7 @@ target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + + set _FLASHNAME $_CHIPNAME.flash +-flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME ++flash bank $_FLASHNAME stm32f1x 0 $_FLASH_SIZE 0 0 $_TARGETNAME + + reset_config srst_nogate + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0044-doc-fix-broken-link-to-IgnoreHardwareSerialNumber-in.patch b/meta-oe/recipes-devtools/openocd/openocd/0044-doc-fix-broken-link-to-IgnoreHardwareSerialNumber-in.patch new file mode 100644 index 000000000..92a20916a --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0044-doc-fix-broken-link-to-IgnoreHardwareSerialNumber-in.patch @@ -0,0 +1,30 @@ +From 98d816ff772ffb45b1f4fbba06cb48b30ca7d98f Mon Sep 17 00:00:00 2001 +From: N S +Date: Wed, 18 Jan 2023 21:58:43 -0800 +Subject: [PATCH] doc: fix broken link to IgnoreHardwareSerialNumber in + README.Windows + + URL for Microsoft documentation on IgnoreHardwareSerialNumber + redirects to generic USB driver landing page instead of specific + article. Update link to go to correct page. + +Signed-off-by: N S +Change-Id: Ifac6c730a1438242cdfe0a0a2867e043e03ceec7 +Reviewed-on: https://review.openocd.org/c/openocd/+/7439 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + README.Windows | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/README.Windows b/README.Windows +index 7326a356c..64bf5c0c6 100644 +--- a/README.Windows ++++ b/README.Windows +@@ -52,5 +52,5 @@ port depending on which application to use. + + For more information, see: + +- http://msdn.microsoft.com/en-us/library/windows/hardware/jj649944(v=vs.85).aspx ++ https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-device-specific-registry-settings + http://www.ftdichip.com/Support/Knowledgebase/index.html?ignorehardwareserialnumber.htm diff --git a/meta-oe/recipes-devtools/openocd/openocd/0045-doc-usb_adapters-add-lsusb-dump-of-esp_usb_jtag.patch b/meta-oe/recipes-devtools/openocd/openocd/0045-doc-usb_adapters-add-lsusb-dump-of-esp_usb_jtag.patch new file mode 100644 index 000000000..f81687d89 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0045-doc-usb_adapters-add-lsusb-dump-of-esp_usb_jtag.patch @@ -0,0 +1,185 @@ +From 41231db3f08150145fe7ddde53cd027e72128d4c Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Fri, 20 Jan 2023 18:33:43 +0100 +Subject: [PATCH] doc:usb_adapters: add lsusb dump of esp_usb_jtag + +Also, esp_usb_jtag added to the supported driver list of +"adapter serial" command. + +Signed-off-by: Erhan Kurubas +Change-Id: Ie65cbf9b44f5de6d7995102d1a281161468f6103 +Reviewed-on: https://review.openocd.org/c/openocd/+/7440 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + doc/openocd.texi | 2 +- + .../esp_usb_jtag/303a_1001_esp_usb_jtag.txt | 134 ++++++++++++++++++ + doc/usb_adapters/readme.txt | 1 + + 3 files changed, 136 insertions(+), 1 deletion(-) + create mode 100644 doc/usb_adapters/esp_usb_jtag/303a_1001_esp_usb_jtag.txt + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index aa1707b7d..b9ad3ff77 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -2480,7 +2480,7 @@ This command is only available if your libusb1 is at least version 1.0.16. + Specifies the @var{serial_string} of the adapter to use. + If this command is not specified, serial strings are not checked. + Only the following adapter drivers use the serial string from this command: +-arm-jtag-ew, cmsis_dap, ft232r, ftdi, hla (stlink, ti-icdi), jlink, kitprog, opendus, ++arm-jtag-ew, cmsis_dap, esp_usb_jtag, ft232r, ftdi, hla (stlink, ti-icdi), jlink, kitprog, opendus, + openjtag, osbdm, presto, rlink, st-link, usb_blaster (ublast2), usbprog, vsllink, xds110. + @end deffn + +diff --git a/doc/usb_adapters/esp_usb_jtag/303a_1001_esp_usb_jtag.txt b/doc/usb_adapters/esp_usb_jtag/303a_1001_esp_usb_jtag.txt +new file mode 100644 +index 000000000..8da58e581 +--- /dev/null ++++ b/doc/usb_adapters/esp_usb_jtag/303a_1001_esp_usb_jtag.txt +@@ -0,0 +1,134 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later ++ ++# Optional comment ++ ++Bus 002 Device 035: ID 303a:1001 ++Device Descriptor: ++ bLength 18 ++ bDescriptorType 1 ++ bcdUSB 2.00 ++ bDeviceClass 239 Miscellaneous Device ++ bDeviceSubClass 2 ++ bDeviceProtocol 1 Interface Association ++ bMaxPacketSize0 64 ++ idVendor 0x303a ++ idProduct 0x1001 ++ bcdDevice 1.01 ++ iManufacturer 1 Espressif ++ iProduct 2 USB JTAG/serial debug unit ++ iSerial 3 7C:DF:A1:A2:8F:38 ++ bNumConfigurations 1 ++ Configuration Descriptor: ++ bLength 9 ++ bDescriptorType 2 ++ wTotalLength 0x0062 ++ bNumInterfaces 3 ++ bConfigurationValue 1 ++ iConfiguration 0 ++ bmAttributes 0xc0 ++ Self Powered ++ MaxPower 500mA ++ Interface Association: ++ bLength 8 ++ bDescriptorType 11 ++ bFirstInterface 0 ++ bInterfaceCount 2 ++ bFunctionClass 2 Communications ++ bFunctionSubClass 2 Abstract (modem) ++ bFunctionProtocol 0 ++ iFunction 0 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 0 ++ bAlternateSetting 0 ++ bNumEndpoints 1 ++ bInterfaceClass 2 Communications ++ bInterfaceSubClass 2 Abstract (modem) ++ bInterfaceProtocol 0 ++ iInterface 0 ++ CDC Header: ++ bcdCDC 1.10 ++ CDC ACM: ++ bmCapabilities 0x02 ++ line coding and serial state ++ CDC Union: ++ bMasterInterface 0 ++ bSlaveInterface 1 ++ CDC Call Management: ++ bmCapabilities 0x03 ++ call management ++ use DataInterface ++ bDataInterface 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x82 EP 2 IN ++ bmAttributes 3 ++ Transfer Type Interrupt ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 1 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 10 CDC Data ++ bInterfaceSubClass 2 ++ bInterfaceProtocol 0 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x01 EP 1 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x81 EP 1 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Interface Descriptor: ++ bLength 9 ++ bDescriptorType 4 ++ bInterfaceNumber 2 ++ bAlternateSetting 0 ++ bNumEndpoints 2 ++ bInterfaceClass 255 Vendor Specific Class ++ bInterfaceSubClass 255 Vendor Specific Subclass ++ bInterfaceProtocol 1 ++ iInterface 0 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x02 EP 2 OUT ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++ Endpoint Descriptor: ++ bLength 7 ++ bDescriptorType 5 ++ bEndpointAddress 0x83 EP 3 IN ++ bmAttributes 2 ++ Transfer Type Bulk ++ Synch Type None ++ Usage Type Data ++ wMaxPacketSize 0x0040 1x 64 bytes ++ bInterval 1 ++Device Status: 0x0001 ++ Self Powered +diff --git a/doc/usb_adapters/readme.txt b/doc/usb_adapters/readme.txt +index 1d995e99f..19df4cf70 100644 +--- a/doc/usb_adapters/readme.txt ++++ b/doc/usb_adapters/readme.txt +@@ -15,6 +15,7 @@ OpenOCD gerrit, as explained in HACKING. + + The dumps are organized in subfolders corresponding to OpenOCD drivers: + - cmsis_dap; ++- esp_usb_jtag; + - ft232r; + - ftdi; + - icdi; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0046-rtos-nuttx-move-stacking-info-to-the-new-nuttx-stack.patch b/meta-oe/recipes-devtools/openocd/openocd/0046-rtos-nuttx-move-stacking-info-to-the-new-nuttx-stack.patch new file mode 100644 index 000000000..53c7c77fd --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0046-rtos-nuttx-move-stacking-info-to-the-new-nuttx-stack.patch @@ -0,0 +1,204 @@ +From 463df952157227866335e398102abe960ffa4131 Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Wed, 5 Oct 2022 17:59:54 +0200 +Subject: [PATCH] rtos/nuttx: move stacking info to the new nuttx stackings + file + +Other OSes have separate files to keep stack register offsets. +Adding them for NuttX as well will provide a clearer way to expand. + +Signed-off-by: Erhan Kurubas +Change-Id: I1428fefefa199a95431f2073c0279dd7028ad8da +Reviewed-on: https://review.openocd.org/c/openocd/+/7250 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/rtos/Makefile.am | 2 ++ + src/rtos/nuttx.c | 58 +----------------------------- + src/rtos/rtos_nuttx_stackings.c | 64 +++++++++++++++++++++++++++++++++ + src/rtos/rtos_nuttx_stackings.h | 11 ++++++ + 4 files changed, 78 insertions(+), 57 deletions(-) + create mode 100644 src/rtos/rtos_nuttx_stackings.c + create mode 100644 src/rtos/rtos_nuttx_stackings.h + +diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am +index f00d7194e..fc3ab8b42 100644 +--- a/src/rtos/Makefile.am ++++ b/src/rtos/Makefile.am +@@ -10,6 +10,7 @@ noinst_LTLIBRARIES += %D%/librtos.la + %D%/rtos_mqx_stackings.c \ + %D%/rtos_ucos_iii_stackings.c \ + %D%/rtos_riot_stackings.c \ ++ %D%/rtos_nuttx_stackings.c \ + %D%/FreeRTOS.c \ + %D%/ThreadX.c \ + %D%/eCos.c \ +@@ -32,4 +33,5 @@ noinst_LTLIBRARIES += %D%/librtos.la + %D%/rtos_mqx_stackings.h \ + %D%/rtos_riot_stackings.h \ + %D%/rtos_ucos_iii_stackings.h \ ++ %D%/rtos_nuttx_stackings.h \ + %D%/nuttx_header.h +diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c +index 87b28c632..993ff84bd 100644 +--- a/src/rtos/nuttx.c ++++ b/src/rtos/nuttx.c +@@ -21,7 +21,7 @@ + #include "server/gdb_server.h" + + #include "nuttx_header.h" +- ++#include "rtos_nuttx_stackings.h" + + int rtos_thread_packet(struct connection *connection, const char *packet, int packet_size); + +@@ -85,62 +85,6 @@ static char *task_state_str[] = { + #endif /* CONFIG_PAGING */ + }; + +-/* see arch/arm/include/armv7-m/irq_cmnvector.h */ +-static const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = { +- { ARMV7M_R0, 0x28, 32 }, /* r0 */ +- { ARMV7M_R1, 0x2c, 32 }, /* r1 */ +- { ARMV7M_R2, 0x30, 32 }, /* r2 */ +- { ARMV7M_R3, 0x34, 32 }, /* r3 */ +- { ARMV7M_R4, 0x08, 32 }, /* r4 */ +- { ARMV7M_R5, 0x0c, 32 }, /* r5 */ +- { ARMV7M_R6, 0x10, 32 }, /* r6 */ +- { ARMV7M_R7, 0x14, 32 }, /* r7 */ +- { ARMV7M_R8, 0x18, 32 }, /* r8 */ +- { ARMV7M_R9, 0x1c, 32 }, /* r9 */ +- { ARMV7M_R10, 0x20, 32 }, /* r10 */ +- { ARMV7M_R11, 0x24, 32 }, /* r11 */ +- { ARMV7M_R12, 0x38, 32 }, /* r12 */ +- { ARMV7M_R13, 0, 32 }, /* sp */ +- { ARMV7M_R14, 0x3c, 32 }, /* lr */ +- { ARMV7M_PC, 0x40, 32 }, /* pc */ +- { ARMV7M_XPSR, 0x44, 32 }, /* xPSR */ +-}; +- +- +-static const struct rtos_register_stacking nuttx_stacking_cortex_m = { +- .stack_registers_size = 0x48, +- .stack_growth_direction = -1, +- .num_output_registers = 17, +- .register_offsets = nuttx_stack_offsets_cortex_m +-}; +- +-static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = { +- { ARMV7M_R0, 0x6c, 32 }, /* r0 */ +- { ARMV7M_R1, 0x70, 32 }, /* r1 */ +- { ARMV7M_R2, 0x74, 32 }, /* r2 */ +- { ARMV7M_R3, 0x78, 32 }, /* r3 */ +- { ARMV7M_R4, 0x08, 32 }, /* r4 */ +- { ARMV7M_R5, 0x0c, 32 }, /* r5 */ +- { ARMV7M_R6, 0x10, 32 }, /* r6 */ +- { ARMV7M_R7, 0x14, 32 }, /* r7 */ +- { ARMV7M_R8, 0x18, 32 }, /* r8 */ +- { ARMV7M_R9, 0x1c, 32 }, /* r9 */ +- { ARMV7M_R10, 0x20, 32 }, /* r10 */ +- { ARMV7M_R11, 0x24, 32 }, /* r11 */ +- { ARMV7M_R12, 0x7c, 32 }, /* r12 */ +- { ARMV7M_R13, 0, 32 }, /* sp */ +- { ARMV7M_R14, 0x80, 32 }, /* lr */ +- { ARMV7M_PC, 0x84, 32 }, /* pc */ +- { ARMV7M_XPSR, 0x88, 32 }, /* xPSR */ +-}; +- +-static const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = { +- .stack_registers_size = 0x8c, +- .stack_growth_direction = -1, +- .num_output_registers = 17, +- .register_offsets = nuttx_stack_offsets_cortex_m_fpu +-}; +- + static int pid_offset = PID; + static int state_offset = STATE; + static int name_offset = NAME; +diff --git a/src/rtos/rtos_nuttx_stackings.c b/src/rtos/rtos_nuttx_stackings.c +new file mode 100644 +index 000000000..cb3a2b9b2 +--- /dev/null ++++ b/src/rtos/rtos_nuttx_stackings.c +@@ -0,0 +1,64 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include "rtos.h" ++#include "target/armv7m.h" ++#include "rtos_nuttx_stackings.h" ++ ++/* see arch/arm/include/armv7-m/irq_cmnvector.h */ ++static const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = { ++ { ARMV7M_R0, 0x28, 32 }, /* r0 */ ++ { ARMV7M_R1, 0x2c, 32 }, /* r1 */ ++ { ARMV7M_R2, 0x30, 32 }, /* r2 */ ++ { ARMV7M_R3, 0x34, 32 }, /* r3 */ ++ { ARMV7M_R4, 0x08, 32 }, /* r4 */ ++ { ARMV7M_R5, 0x0c, 32 }, /* r5 */ ++ { ARMV7M_R6, 0x10, 32 }, /* r6 */ ++ { ARMV7M_R7, 0x14, 32 }, /* r7 */ ++ { ARMV7M_R8, 0x18, 32 }, /* r8 */ ++ { ARMV7M_R9, 0x1c, 32 }, /* r9 */ ++ { ARMV7M_R10, 0x20, 32 }, /* r10 */ ++ { ARMV7M_R11, 0x24, 32 }, /* r11 */ ++ { ARMV7M_R12, 0x38, 32 }, /* r12 */ ++ { ARMV7M_R13, 0, 32 }, /* sp */ ++ { ARMV7M_R14, 0x3c, 32 }, /* lr */ ++ { ARMV7M_PC, 0x40, 32 }, /* pc */ ++ { ARMV7M_XPSR, 0x44, 32 }, /* xPSR */ ++}; ++ ++const struct rtos_register_stacking nuttx_stacking_cortex_m = { ++ .stack_registers_size = 0x48, ++ .stack_growth_direction = -1, ++ .num_output_registers = 17, ++ .register_offsets = nuttx_stack_offsets_cortex_m, ++}; ++ ++static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = { ++ { ARMV7M_R0, 0x6c, 32 }, /* r0 */ ++ { ARMV7M_R1, 0x70, 32 }, /* r1 */ ++ { ARMV7M_R2, 0x74, 32 }, /* r2 */ ++ { ARMV7M_R3, 0x78, 32 }, /* r3 */ ++ { ARMV7M_R4, 0x08, 32 }, /* r4 */ ++ { ARMV7M_R5, 0x0c, 32 }, /* r5 */ ++ { ARMV7M_R6, 0x10, 32 }, /* r6 */ ++ { ARMV7M_R7, 0x14, 32 }, /* r7 */ ++ { ARMV7M_R8, 0x18, 32 }, /* r8 */ ++ { ARMV7M_R9, 0x1c, 32 }, /* r9 */ ++ { ARMV7M_R10, 0x20, 32 }, /* r10 */ ++ { ARMV7M_R11, 0x24, 32 }, /* r11 */ ++ { ARMV7M_R12, 0x7c, 32 }, /* r12 */ ++ { ARMV7M_R13, 0, 32 }, /* sp */ ++ { ARMV7M_R14, 0x80, 32 }, /* lr */ ++ { ARMV7M_PC, 0x84, 32 }, /* pc */ ++ { ARMV7M_XPSR, 0x88, 32 }, /* xPSR */ ++}; ++ ++const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = { ++ .stack_registers_size = 0x8c, ++ .stack_growth_direction = -1, ++ .num_output_registers = 17, ++ .register_offsets = nuttx_stack_offsets_cortex_m_fpu, ++}; +diff --git a/src/rtos/rtos_nuttx_stackings.h b/src/rtos/rtos_nuttx_stackings.h +new file mode 100644 +index 000000000..bfbc049f8 +--- /dev/null ++++ b/src/rtos/rtos_nuttx_stackings.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++#ifndef INCLUDED_RTOS_NUTTX_STACKINGS_H ++#define INCLUDED_RTOS_NUTTX_STACKINGS_H ++ ++#include "rtos.h" ++ ++extern const struct rtos_register_stacking nuttx_stacking_cortex_m; ++extern const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu; ++ ++#endif /* INCLUDED_RTOS_NUTTX_STACKINGS_H */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0047-rtos-nuttx-add-riscv-stacking-info.patch b/meta-oe/recipes-devtools/openocd/openocd/0047-rtos-nuttx-add-riscv-stacking-info.patch new file mode 100644 index 000000000..3a3c1a733 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0047-rtos-nuttx-add-riscv-stacking-info.patch @@ -0,0 +1,89 @@ +From dfbbfac4d72e247e8094a49c8573b2f49689b6d5 Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Wed, 5 Oct 2022 18:38:23 +0200 +Subject: [PATCH] rtos/nuttx: add riscv stacking info + +Tested with Espressif ESP32-C3 MCU + +Signed-off-by: Erhan Kurubas +Change-Id: Ia71ace4909f2dc93ddc07a2ec5524cf374f1937c +Reviewed-on: https://review.openocd.org/c/openocd/+/7251 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/rtos/rtos_nuttx_stackings.c | 46 +++++++++++++++++++++++++++++++++ + src/rtos/rtos_nuttx_stackings.h | 1 + + 2 files changed, 47 insertions(+) + +diff --git a/src/rtos/rtos_nuttx_stackings.c b/src/rtos/rtos_nuttx_stackings.c +index cb3a2b9b2..b59b1356b 100644 +--- a/src/rtos/rtos_nuttx_stackings.c ++++ b/src/rtos/rtos_nuttx_stackings.c +@@ -7,6 +7,8 @@ + #include "rtos.h" + #include "target/armv7m.h" + #include "rtos_nuttx_stackings.h" ++#include "rtos_standard_stackings.h" ++#include + + /* see arch/arm/include/armv7-m/irq_cmnvector.h */ + static const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = { +@@ -62,3 +64,47 @@ const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = { + .num_output_registers = 17, + .register_offsets = nuttx_stack_offsets_cortex_m_fpu, + }; ++ ++static const struct stack_register_offset nuttx_stack_offsets_riscv[] = { ++ { GDB_REGNO_ZERO, -1, 32 }, ++ { GDB_REGNO_RA, 0x04, 32 }, ++ { GDB_REGNO_SP, 0x08, 32 }, ++ { GDB_REGNO_GP, 0x0c, 32 }, ++ { GDB_REGNO_TP, 0x10, 32 }, ++ { GDB_REGNO_T0, 0x14, 32 }, ++ { GDB_REGNO_T1, 0x18, 32 }, ++ { GDB_REGNO_T2, 0x1c, 32 }, ++ { GDB_REGNO_FP, 0x20, 32 }, ++ { GDB_REGNO_S1, 0x24, 32 }, ++ { GDB_REGNO_A0, 0x28, 32 }, ++ { GDB_REGNO_A1, 0x2c, 32 }, ++ { GDB_REGNO_A2, 0x30, 32 }, ++ { GDB_REGNO_A3, 0x34, 32 }, ++ { GDB_REGNO_A4, 0x38, 32 }, ++ { GDB_REGNO_A5, 0x3c, 32 }, ++ { GDB_REGNO_A6, 0x40, 32 }, ++ { GDB_REGNO_A7, 0x44, 32 }, ++ { GDB_REGNO_S2, 0x48, 32 }, ++ { GDB_REGNO_S3, 0x4c, 32 }, ++ { GDB_REGNO_S4, 0x50, 32 }, ++ { GDB_REGNO_S5, 0x54, 32 }, ++ { GDB_REGNO_S6, 0x58, 32 }, ++ { GDB_REGNO_S7, 0x5c, 32 }, ++ { GDB_REGNO_S8, 0x60, 32 }, ++ { GDB_REGNO_S9, 0x64, 32 }, ++ { GDB_REGNO_S10, 0x68, 32 }, ++ { GDB_REGNO_S11, 0x6c, 32 }, ++ { GDB_REGNO_T3, 0x70, 32 }, ++ { GDB_REGNO_T4, 0x74, 32 }, ++ { GDB_REGNO_T5, 0x78, 32 }, ++ { GDB_REGNO_T6, 0x7c, 32 }, ++ { GDB_REGNO_PC, 0x00, 32 }, ++}; ++ ++const struct rtos_register_stacking nuttx_riscv_stacking = { ++ .stack_registers_size = 33 * 4, ++ .stack_growth_direction = -1, ++ .num_output_registers = 33, ++ .calculate_process_stack = rtos_generic_stack_align8, ++ .register_offsets = nuttx_stack_offsets_riscv, ++}; +diff --git a/src/rtos/rtos_nuttx_stackings.h b/src/rtos/rtos_nuttx_stackings.h +index bfbc049f8..2e5f09212 100644 +--- a/src/rtos/rtos_nuttx_stackings.h ++++ b/src/rtos/rtos_nuttx_stackings.h +@@ -7,5 +7,6 @@ + + extern const struct rtos_register_stacking nuttx_stacking_cortex_m; + extern const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu; ++extern const struct rtos_register_stacking nuttx_riscv_stacking; + + #endif /* INCLUDED_RTOS_NUTTX_STACKINGS_H */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0048-rtos-add-custom-stack-read-function.patch b/meta-oe/recipes-devtools/openocd/openocd/0048-rtos-add-custom-stack-read-function.patch new file mode 100644 index 000000000..626b3b674 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0048-rtos-add-custom-stack-read-function.patch @@ -0,0 +1,52 @@ +From 59bc761d56f9ce9a76c917e267a2c37f1a680611 Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Sat, 21 Jan 2023 20:10:21 +0100 +Subject: [PATCH] rtos: add custom stack read function + +This is optional field for the targets which has to implement +their custom stack read function. + +Signed-off-by: Erhan Kurubas +Change-Id: Icbc9ed66a052fc2cc0ef67e3ec4d85ab0c2c1b94 +Reviewed-on: https://review.openocd.org/c/openocd/+/7442 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/rtos/rtos.c | 5 ++++- + src/rtos/rtos.h | 7 +++++++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c +index 2e76b501a..dfa158d01 100644 +--- a/src/rtos/rtos.c ++++ b/src/rtos/rtos.c +@@ -632,7 +632,10 @@ int rtos_generic_stack_read(struct target *target, + + if (stacking->stack_growth_direction == 1) + address -= stacking->stack_registers_size; +- retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data); ++ if (stacking->read_stack) ++ retval = stacking->read_stack(target, address, stacking, stack_data); ++ else ++ retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data); + if (retval != ERROR_OK) { + free(stack_data); + LOG_ERROR("Error reading stack frame from thread"); +diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h +index ace57514a..9128c163c 100644 +--- a/src/rtos/rtos.h ++++ b/src/rtos/rtos.h +@@ -102,6 +102,13 @@ struct rtos_register_stacking { + const struct rtos_register_stacking *stacking, + target_addr_t stack_ptr); + const struct stack_register_offset *register_offsets; ++ /* Optional field for targets which may have to implement their own stack read function. ++ * Because stack format can be weird or stack data needed to be edited before passing to the gdb. ++ */ ++ int (*read_stack)(struct target *target, ++ int64_t stack_ptr, ++ const struct rtos_register_stacking *stacking, ++ uint8_t *stack_data); + }; + + #define GDB_THREAD_PACKET_NOT_CONSUMED (-40) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0049-rtos-nuttx-add-stacking-info-for-Espressif-Xtensa-ch.patch b/meta-oe/recipes-devtools/openocd/openocd/0049-rtos-nuttx-add-stacking-info-for-Espressif-Xtensa-ch.patch new file mode 100644 index 000000000..a4cdebd65 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0049-rtos-nuttx-add-stacking-info-for-Espressif-Xtensa-ch.patch @@ -0,0 +1,382 @@ +From cf50bcb841238726697dc1250d6b6cb49fc6d19d Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Sat, 21 Jan 2023 20:23:07 +0100 +Subject: [PATCH] rtos/nuttx: add stacking info for Espressif Xtensa chips + +ESP32, ESP32-S2 and ESP32-S3 stack register offsets added + +Signed-off-by: Erhan Kurubas +Change-Id: Ic6215c1d0152853fd08f82cbd3c138c7d62dbc46 +Reviewed-on: https://review.openocd.org/c/openocd/+/7443 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/rtos/rtos_nuttx_stackings.c | 358 ++++++++++++++++++++++++++++++++ + 1 file changed, 358 insertions(+) + +diff --git a/src/rtos/rtos_nuttx_stackings.c b/src/rtos/rtos_nuttx_stackings.c +index b59b1356b..b70cccb33 100644 +--- a/src/rtos/rtos_nuttx_stackings.c ++++ b/src/rtos/rtos_nuttx_stackings.c +@@ -108,3 +108,361 @@ const struct rtos_register_stacking nuttx_riscv_stacking = { + .calculate_process_stack = rtos_generic_stack_align8, + .register_offsets = nuttx_stack_offsets_riscv, + }; ++ ++static int nuttx_esp_xtensa_stack_read(struct target *target, ++ int64_t stack_ptr, const struct rtos_register_stacking *stacking, ++ uint8_t *stack_data) ++{ ++ int retval = target_read_buffer(target, stack_ptr, stacking->stack_registers_size, stack_data); ++ if (retval != ERROR_OK) ++ return retval; ++ ++ stack_data[4] &= ~0x10; /* Clear exception bit in PS */ ++ ++ return ERROR_OK; ++} ++ ++static const struct stack_register_offset nuttx_stack_offsets_esp32[] = { ++ { 0, 0x00, 32 }, /* PC */ ++ { 1, 0x08, 32 }, /* A0 */ ++ { 2, 0x0c, 32 }, /* A1 */ ++ { 3, 0x10, 32 }, /* A2 */ ++ { 4, 0x14, 32 }, /* A3 */ ++ { 5, 0x18, 32 }, /* A4 */ ++ { 6, 0x1c, 32 }, /* A5 */ ++ { 7, 0x20, 32 }, /* A6 */ ++ { 8, 0x24, 32 }, /* A7 */ ++ { 9, 0x28, 32 }, /* A8 */ ++ { 10, 0x2c, 32 }, /* A9 */ ++ { 11, 0x30, 32 }, /* A10 */ ++ { 12, 0x34, 32 }, /* A11 */ ++ { 13, 0x38, 32 }, /* A12 */ ++ { 14, 0x3c, 32 }, /* A13 */ ++ { 15, 0x40, 32 }, /* A14 */ ++ { 16, 0x44, 32 }, /* A15 */ ++ /* A16-A63 aren't in the stack frame because they've been flushed to the stack earlier */ ++ { 17, -1, 32 }, /* A16 */ ++ { 18, -1, 32 }, /* A17 */ ++ { 19, -1, 32 }, /* A18 */ ++ { 20, -1, 32 }, /* A19 */ ++ { 21, -1, 32 }, /* A20 */ ++ { 22, -1, 32 }, /* A21 */ ++ { 23, -1, 32 }, /* A22 */ ++ { 24, -1, 32 }, /* A23 */ ++ { 25, -1, 32 }, /* A24 */ ++ { 26, -1, 32 }, /* A25 */ ++ { 27, -1, 32 }, /* A26 */ ++ { 28, -1, 32 }, /* A27 */ ++ { 29, -1, 32 }, /* A28 */ ++ { 30, -1, 32 }, /* A29 */ ++ { 31, -1, 32 }, /* A30 */ ++ { 32, -1, 32 }, /* A31 */ ++ { 33, -1, 32 }, /* A32 */ ++ { 34, -1, 32 }, /* A33 */ ++ { 35, -1, 32 }, /* A34 */ ++ { 36, -1, 32 }, /* A35 */ ++ { 37, -1, 32 }, /* A36 */ ++ { 38, -1, 32 }, /* A37 */ ++ { 39, -1, 32 }, /* A38 */ ++ { 40, -1, 32 }, /* A39 */ ++ { 41, -1, 32 }, /* A40 */ ++ { 42, -1, 32 }, /* A41 */ ++ { 43, -1, 32 }, /* A42 */ ++ { 44, -1, 32 }, /* A43 */ ++ { 45, -1, 32 }, /* A44 */ ++ { 46, -1, 32 }, /* A45 */ ++ { 47, -1, 32 }, /* A46 */ ++ { 48, -1, 32 }, /* A47 */ ++ { 49, -1, 32 }, /* A48 */ ++ { 50, -1, 32 }, /* A49 */ ++ { 51, -1, 32 }, /* A50 */ ++ { 52, -1, 32 }, /* A51 */ ++ { 53, -1, 32 }, /* A52 */ ++ { 54, -1, 32 }, /* A53 */ ++ { 55, -1, 32 }, /* A54 */ ++ { 56, -1, 32 }, /* A55 */ ++ { 57, -1, 32 }, /* A56 */ ++ { 58, -1, 32 }, /* A57 */ ++ { 59, -1, 32 }, /* A58 */ ++ { 60, -1, 32 }, /* A59 */ ++ { 61, -1, 32 }, /* A60 */ ++ { 62, -1, 32 }, /* A61 */ ++ { 63, -1, 32 }, /* A62 */ ++ { 64, -1, 32 }, /* A63 */ ++ { 65, 0x58, 32 }, /* lbeg */ ++ { 66, 0x5c, 32 }, /* lend */ ++ { 67, 0x60, 32 }, /* lcount */ ++ { 68, 0x48, 32 }, /* SAR */ ++ { 69, -1, 32 }, /* windowbase */ ++ { 70, -1, 32 }, /* windowstart */ ++ { 71, -1, 32 }, /* configid0 */ ++ { 72, -1, 32 }, /* configid1 */ ++ { 73, 0x04, 32 }, /* PS */ ++ { 74, -1, 32 }, /* threadptr */ ++ { 75, -1, 32 }, /* br */ ++ { 76, 0x54, 32 }, /* scompare1 */ ++ { 77, -1, 32 }, /* acclo */ ++ { 78, -1, 32 }, /* acchi */ ++ { 79, -1, 32 }, /* m0 */ ++ { 80, -1, 32 }, /* m1 */ ++ { 81, -1, 32 }, /* m2 */ ++ { 82, -1, 32 }, /* m3 */ ++ { 83, -1, 32 }, /* expstate */ ++ { 84, -1, 32 }, /* f64r_lo */ ++ { 85, -1, 32 }, /* f64r_hi */ ++ { 86, -1, 32 }, /* f64s */ ++ { 87, -1, 32 }, /* f0 */ ++ { 88, -1, 32 }, /* f1 */ ++ { 89, -1, 32 }, /* f2 */ ++ { 90, -1, 32 }, /* f3 */ ++ { 91, -1, 32 }, /* f4 */ ++ { 92, -1, 32 }, /* f5 */ ++ { 93, -1, 32 }, /* f6 */ ++ { 94, -1, 32 }, /* f7 */ ++ { 95, -1, 32 }, /* f8 */ ++ { 96, -1, 32 }, /* f9 */ ++ { 97, -1, 32 }, /* f10 */ ++ { 98, -1, 32 }, /* f11 */ ++ { 99, -1, 32 }, /* f12 */ ++ { 100, -1, 32 }, /* f13 */ ++ { 101, -1, 32 }, /* f14 */ ++ { 102, -1, 32 }, /* f15 */ ++ { 103, -1, 32 }, /* fcr */ ++ { 104, -1, 32 }, /* fsr */ ++}; ++ ++const struct rtos_register_stacking nuttx_esp32_stacking = { ++ .stack_registers_size = 26 * 4, ++ .stack_growth_direction = -1, ++ .num_output_registers = ARRAY_SIZE(nuttx_stack_offsets_esp32), ++ .calculate_process_stack = rtos_generic_stack_align8, ++ .register_offsets = nuttx_stack_offsets_esp32, ++ .read_stack = nuttx_esp_xtensa_stack_read, ++}; ++ ++static const struct stack_register_offset nuttx_stack_offsets_esp32s2[] = { ++ { 0, 0x00, 32 }, /* PC */ ++ { 1, 0x08, 32 }, /* A0 */ ++ { 2, 0x0c, 32 }, /* A1 */ ++ { 3, 0x10, 32 }, /* A2 */ ++ { 4, 0x14, 32 }, /* A3 */ ++ { 5, 0x18, 32 }, /* A4 */ ++ { 6, 0x1c, 32 }, /* A5 */ ++ { 7, 0x20, 32 }, /* A6 */ ++ { 8, 0x24, 32 }, /* A7 */ ++ { 9, 0x28, 32 }, /* A8 */ ++ { 10, 0x2c, 32 }, /* A9 */ ++ { 11, 0x30, 32 }, /* A10 */ ++ { 12, 0x34, 32 }, /* A11 */ ++ { 13, 0x38, 32 }, /* A12 */ ++ { 14, 0x3c, 32 }, /* A13 */ ++ { 15, 0x40, 32 }, /* A14 */ ++ { 16, 0x44, 32 }, /* A15 */ ++ /* A16-A63 aren't in the stack frame because they've been flushed to the stack earlier */ ++ { 17, -1, 32 }, /* A16 */ ++ { 18, -1, 32 }, /* A17 */ ++ { 19, -1, 32 }, /* A18 */ ++ { 20, -1, 32 }, /* A19 */ ++ { 21, -1, 32 }, /* A20 */ ++ { 22, -1, 32 }, /* A21 */ ++ { 23, -1, 32 }, /* A22 */ ++ { 24, -1, 32 }, /* A23 */ ++ { 25, -1, 32 }, /* A24 */ ++ { 26, -1, 32 }, /* A25 */ ++ { 27, -1, 32 }, /* A26 */ ++ { 28, -1, 32 }, /* A27 */ ++ { 29, -1, 32 }, /* A28 */ ++ { 30, -1, 32 }, /* A29 */ ++ { 31, -1, 32 }, /* A30 */ ++ { 32, -1, 32 }, /* A31 */ ++ { 33, -1, 32 }, /* A32 */ ++ { 34, -1, 32 }, /* A33 */ ++ { 35, -1, 32 }, /* A34 */ ++ { 36, -1, 32 }, /* A35 */ ++ { 37, -1, 32 }, /* A36 */ ++ { 38, -1, 32 }, /* A37 */ ++ { 39, -1, 32 }, /* A38 */ ++ { 40, -1, 32 }, /* A39 */ ++ { 41, -1, 32 }, /* A40 */ ++ { 42, -1, 32 }, /* A41 */ ++ { 43, -1, 32 }, /* A42 */ ++ { 44, -1, 32 }, /* A43 */ ++ { 45, -1, 32 }, /* A44 */ ++ { 46, -1, 32 }, /* A45 */ ++ { 47, -1, 32 }, /* A46 */ ++ { 48, -1, 32 }, /* A47 */ ++ { 49, -1, 32 }, /* A48 */ ++ { 50, -1, 32 }, /* A49 */ ++ { 51, -1, 32 }, /* A50 */ ++ { 52, -1, 32 }, /* A51 */ ++ { 53, -1, 32 }, /* A52 */ ++ { 54, -1, 32 }, /* A53 */ ++ { 55, -1, 32 }, /* A54 */ ++ { 56, -1, 32 }, /* A55 */ ++ { 57, -1, 32 }, /* A56 */ ++ { 58, -1, 32 }, /* A57 */ ++ { 59, -1, 32 }, /* A58 */ ++ { 60, -1, 32 }, /* A59 */ ++ { 61, -1, 32 }, /* A60 */ ++ { 62, -1, 32 }, /* A61 */ ++ { 63, -1, 32 }, /* A62 */ ++ { 64, -1, 32 }, /* A63 */ ++ { 65, 0x48, 32 }, /* SAR */ ++ { 66, -1, 32 }, /* windowbase */ ++ { 67, -1, 32 }, /* windowstart */ ++ { 68, -1, 32 }, /* configid0 */ ++ { 69, -1, 32 }, /* configid1 */ ++ { 70, 0x04, 32 }, /* PS */ ++ { 71, -1, 32 }, /* threadptr */ ++ { 72, -1, 32 }, /* gpio_out */ ++}; ++ ++const struct rtos_register_stacking nuttx_esp32s2_stacking = { ++ .stack_registers_size = 25 * 4, ++ .stack_growth_direction = -1, ++ .num_output_registers = ARRAY_SIZE(nuttx_stack_offsets_esp32s2), ++ .calculate_process_stack = rtos_generic_stack_align8, ++ .register_offsets = nuttx_stack_offsets_esp32s2, ++ .read_stack = nuttx_esp_xtensa_stack_read, ++}; ++ ++static const struct stack_register_offset nuttx_stack_offsets_esp32s3[] = { ++ { 0, 0x00, 32 }, /* PC */ ++ { 1, 0x08, 32 }, /* A0 */ ++ { 2, 0x0c, 32 }, /* A1 */ ++ { 3, 0x10, 32 }, /* A2 */ ++ { 4, 0x14, 32 }, /* A3 */ ++ { 5, 0x18, 32 }, /* A4 */ ++ { 6, 0x1c, 32 }, /* A5 */ ++ { 7, 0x20, 32 }, /* A6 */ ++ { 8, 0x24, 32 }, /* A7 */ ++ { 9, 0x28, 32 }, /* A8 */ ++ { 10, 0x2c, 32 }, /* A9 */ ++ { 11, 0x30, 32 }, /* A10 */ ++ { 12, 0x34, 32 }, /* A11 */ ++ { 13, 0x38, 32 }, /* A12 */ ++ { 14, 0x3c, 32 }, /* A13 */ ++ { 15, 0x40, 32 }, /* A14 */ ++ { 16, 0x44, 32 }, /* A15 */ ++ /* A16-A63 aren't in the stack frame because they've been flushed to the stack earlier */ ++ { 17, -1, 32 }, /* A16 */ ++ { 18, -1, 32 }, /* A17 */ ++ { 19, -1, 32 }, /* A18 */ ++ { 20, -1, 32 }, /* A19 */ ++ { 21, -1, 32 }, /* A20 */ ++ { 22, -1, 32 }, /* A21 */ ++ { 23, -1, 32 }, /* A22 */ ++ { 24, -1, 32 }, /* A23 */ ++ { 25, -1, 32 }, /* A24 */ ++ { 26, -1, 32 }, /* A25 */ ++ { 27, -1, 32 }, /* A26 */ ++ { 28, -1, 32 }, /* A27 */ ++ { 29, -1, 32 }, /* A28 */ ++ { 30, -1, 32 }, /* A29 */ ++ { 31, -1, 32 }, /* A30 */ ++ { 32, -1, 32 }, /* A31 */ ++ { 33, -1, 32 }, /* A32 */ ++ { 34, -1, 32 }, /* A33 */ ++ { 35, -1, 32 }, /* A34 */ ++ { 36, -1, 32 }, /* A35 */ ++ { 37, -1, 32 }, /* A36 */ ++ { 38, -1, 32 }, /* A37 */ ++ { 39, -1, 32 }, /* A38 */ ++ { 40, -1, 32 }, /* A39 */ ++ { 41, -1, 32 }, /* A40 */ ++ { 42, -1, 32 }, /* A41 */ ++ { 43, -1, 32 }, /* A42 */ ++ { 44, -1, 32 }, /* A43 */ ++ { 45, -1, 32 }, /* A44 */ ++ { 46, -1, 32 }, /* A45 */ ++ { 47, -1, 32 }, /* A46 */ ++ { 48, -1, 32 }, /* A47 */ ++ { 49, -1, 32 }, /* A48 */ ++ { 50, -1, 32 }, /* A49 */ ++ { 51, -1, 32 }, /* A50 */ ++ { 52, -1, 32 }, /* A51 */ ++ { 53, -1, 32 }, /* A52 */ ++ { 54, -1, 32 }, /* A53 */ ++ { 55, -1, 32 }, /* A54 */ ++ { 56, -1, 32 }, /* A55 */ ++ { 57, -1, 32 }, /* A56 */ ++ { 58, -1, 32 }, /* A57 */ ++ { 59, -1, 32 }, /* A58 */ ++ { 60, -1, 32 }, /* A59 */ ++ { 61, -1, 32 }, /* A60 */ ++ { 62, -1, 32 }, /* A61 */ ++ { 63, -1, 32 }, /* A62 */ ++ { 64, -1, 32 }, /* A63 */ ++ { 65, 0x58, 32 }, /* lbeg */ ++ { 66, 0x5c, 32 }, /* lend */ ++ { 67, 0x60, 32 }, /* lcount */ ++ { 68, 0x48, 32 }, /* SAR */ ++ { 69, -1, 32 }, /* windowbase */ ++ { 70, -1, 32 }, /* windowstart */ ++ { 71, -1, 32 }, /* configid0 */ ++ { 72, -1, 32 }, /* configid1 */ ++ { 73, 0x04, 32 }, /* PS */ ++ { 74, -1, 32 }, /* threadptr */ ++ { 75, -1, 32 }, /* br */ ++ { 76, 0x54, 32 }, /* scompare1 */ ++ { 77, -1, 32 }, /* acclo */ ++ { 78, -1, 32 }, /* acchi */ ++ { 79, -1, 32 }, /* m0 */ ++ { 80, -1, 32 }, /* m1 */ ++ { 81, -1, 32 }, /* m2 */ ++ { 82, -1, 32 }, /* m3 */ ++ { 83, -1, 32 }, /* gpio_out */ ++ { 84, -1, 32 }, /* f0 */ ++ { 85, -1, 32 }, /* f1 */ ++ { 86, -1, 32 }, /* f2 */ ++ { 87, -1, 32 }, /* f3 */ ++ { 88, -1, 32 }, /* f4 */ ++ { 89, -1, 32 }, /* f5 */ ++ { 90, -1, 32 }, /* f6 */ ++ { 91, -1, 32 }, /* f7 */ ++ { 92, -1, 32 }, /* f8 */ ++ { 93, -1, 32 }, /* f9 */ ++ { 94, -1, 32 }, /* f10 */ ++ { 95, -1, 32 }, /* f11 */ ++ { 96, -1, 32 }, /* f12 */ ++ { 97, -1, 32 }, /* f13 */ ++ { 98, -1, 32 }, /* f14 */ ++ { 99, -1, 32 }, /* f15 */ ++ { 100, -1, 32 }, /* fcr */ ++ { 101, -1, 32 }, /* fsr */ ++ { 102, -1, 32 }, /* accx_0 */ ++ { 103, -1, 32 }, /* accx_1 */ ++ { 104, -1, 32 }, /* qacc_h_0 */ ++ { 105, -1, 32 }, /* qacc_h_1 */ ++ { 106, -1, 32 }, /* qacc_h_2 */ ++ { 107, -1, 32 }, /* qacc_h_3 */ ++ { 108, -1, 32 }, /* qacc_h_4 */ ++ { 109, -1, 32 }, /* qacc_l_0 */ ++ { 110, -1, 32 }, /* qacc_l_1 */ ++ { 111, -1, 32 }, /* qacc_l_2 */ ++ { 112, -1, 32 }, /* qacc_l_3 */ ++ { 113, -1, 32 }, /* qacc_l_4 */ ++ { 114, -1, 32 }, /* sar_byte */ ++ { 115, -1, 32 }, /* fft_bit_width */ ++ { 116, -1, 32 }, /* ua_state_0 */ ++ { 117, -1, 32 }, /* ua_state_1 */ ++ { 118, -1, 32 }, /* ua_state_2 */ ++ { 119, -1, 32 }, /* ua_state_3 */ ++ { 120, -1, 128 }, /* q0 */ ++ { 121, -1, 128 }, /* q1 */ ++ { 122, -1, 128 }, /* q2 */ ++ { 123, -1, 128 }, /* q3 */ ++ { 124, -1, 128 }, /* q4 */ ++ { 125, -1, 128 }, /* q5 */ ++ { 126, -1, 128 }, /* q6 */ ++ { 127, -1, 128 }, /* q7 */ ++}; ++ ++const struct rtos_register_stacking nuttx_esp32s3_stacking = { ++ .stack_registers_size = 26 * 4, ++ .stack_growth_direction = -1, ++ .num_output_registers = ARRAY_SIZE(nuttx_stack_offsets_esp32s3), ++ .calculate_process_stack = rtos_generic_stack_align8, ++ .register_offsets = nuttx_stack_offsets_esp32s3, ++ .read_stack = nuttx_esp_xtensa_stack_read, ++}; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0050-rtos-Support-rt-kernel.patch b/meta-oe/recipes-devtools/openocd/openocd/0050-rtos-Support-rt-kernel.patch new file mode 100644 index 000000000..d8428dc6b --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0050-rtos-Support-rt-kernel.patch @@ -0,0 +1,473 @@ +From 43c8aa28cb1570c11e1099c43e685af228190679 Mon Sep 17 00:00:00 2001 +From: Andreas Fritiofson +Date: Fri, 15 Apr 2016 12:38:43 +0200 +Subject: [PATCH] rtos: Support rt-kernel + +Works for the proprietary rt-kernel from rt-labs. + +See: https://rt-labs.com/product/rt-kernel/ +Change-Id: Id2c2e292c15fb17eab25e3d07db05014daa2a2b0 +Signed-off-by: Andreas Fritiofson +Reviewed-on: https://review.openocd.org/c/openocd/+/6668 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + doc/openocd.texi | 5 +- + src/rtos/Makefile.am | 1 + + src/rtos/rtkernel.c | 384 +++++++++++++++++++++++++++++++++++++++++++ + src/rtos/rtos.c | 2 + + 4 files changed, 391 insertions(+), 1 deletion(-) + create mode 100644 src/rtos/rtkernel.c + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index b9ad3ff77..6c853f2ce 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -5000,7 +5000,7 @@ The value should normally correspond to a static mapping for the + @var{rtos_type} can be one of @option{auto}, @option{none}, @option{eCos}, + @option{ThreadX}, @option{FreeRTOS}, @option{linux}, @option{ChibiOS}, + @option{embKernel}, @option{mqx}, @option{uCOS-III}, @option{nuttx}, +-@option{RIOT}, @option{Zephyr} ++@option{RIOT}, @option{Zephyr}, @option{rtkernel} + @xref{gdbrtossupport,,RTOS Support}. + + @item @code{-defer-examine} -- skip target examination at initial JTAG chain +@@ -11867,6 +11867,7 @@ Currently supported rtos's include: + @item @option{RIOT} + @item @option{hwthread} (This is not an actual RTOS. @xref{usingopenocdsmpwithgdb,,Using OpenOCD SMP with GDB}.) + @item @option{Zephyr} ++@item @option{rtkernel} + @end itemize + + At any time, it's possible to drop the selected RTOS using: +@@ -11908,6 +11909,8 @@ _tcb_name_offset. + @end raggedright + @item Zephyr symbols + _kernel, _kernel_openocd_offsets, _kernel_openocd_size_t_size ++@item rtkernel symbols ++Multiple struct offsets. + @end table + + For most RTOS supported the above symbols will be exported by default. However for +diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am +index fc3ab8b42..b0f7daf5f 100644 +--- a/src/rtos/Makefile.am ++++ b/src/rtos/Makefile.am +@@ -21,6 +21,7 @@ noinst_LTLIBRARIES += %D%/librtos.la + %D%/mqx.c \ + %D%/uCOS-III.c \ + %D%/nuttx.c \ ++ %D%/rtkernel.c \ + %D%/hwthread.c \ + %D%/zephyr.c \ + %D%/riot.c \ +diff --git a/src/rtos/rtkernel.c b/src/rtos/rtkernel.c +new file mode 100644 +index 000000000..ba1de2517 +--- /dev/null ++++ b/src/rtos/rtkernel.c +@@ -0,0 +1,384 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++/*************************************************************************** ++ * Copyright (C) 2016-2023 by Andreas Fritiofson * ++ * andreas.fritiofson@gmail.com * ++ ***************************************************************************/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include "target/target.h" ++#include "target/target_type.h" ++#include "rtos.h" ++#include "helper/log.h" ++#include "helper/types.h" ++#include "rtos_standard_stackings.h" ++#include "target/armv7m.h" ++#include "target/cortex_m.h" ++ ++#define ST_DEAD BIT(0) /* Task is waiting to be deleted */ ++#define ST_WAIT BIT(1) /* Task is blocked: */ ++#define ST_SEM BIT(2) /* on semaphore */ ++#define ST_MTX BIT(3) /* on mutex */ ++#define ST_SIG BIT(4) /* on signal */ ++#define ST_DLY BIT(5) /* on timer */ ++#define ST_FLAG BIT(6) /* on flag */ ++#define ST_FLAG_ALL BIT(7) /* on flag and flag mode is "ALL" */ ++#define ST_MBOX BIT(8) /* on mailbox */ ++#define ST_STP BIT(9) /* self stopped */ ++#define ST_SUSPEND BIT(10) /* Task is suspended */ ++#define ST_TT BIT(11) /* Time triggered task */ ++#define ST_TT_YIELD BIT(12) /* Time triggered task that yields */ ++#define ST_CREATE BIT(13) /* Task was created by task_create() */ ++ ++struct rtkernel_params { ++ const char *target_name; ++ const struct rtos_register_stacking *stacking_info_cm3; ++ const struct rtos_register_stacking *stacking_info_cm4f; ++ const struct rtos_register_stacking *stacking_info_cm4f_fpu; ++}; ++ ++static const struct rtkernel_params rtkernel_params_list[] = { ++ { ++ "cortex_m", /* target_name */ ++ &rtos_standard_cortex_m3_stacking, /* stacking_info */ ++ &rtos_standard_cortex_m4f_stacking, ++ &rtos_standard_cortex_m4f_fpu_stacking, ++ }, ++ { ++ "hla_target", /* target_name */ ++ &rtos_standard_cortex_m3_stacking, /* stacking_info */ ++ &rtos_standard_cortex_m4f_stacking, ++ &rtos_standard_cortex_m4f_fpu_stacking, ++ }, ++}; ++ ++enum rtkernel_symbol_values { ++ sym_os_state = 0, ++ sym___off_os_state2chain = 1, ++ sym___off_os_state2current = 2, ++ sym___off_task2chain = 3, ++ sym___off_task2magic = 4, ++ sym___off_task2stack = 5, ++ sym___off_task2state = 6, ++ sym___off_task2name = 7, ++ sym___val_task_magic = 8, ++}; ++ ++struct symbols { ++ const char *name; ++ bool optional; ++}; ++ ++static const struct symbols rtkernel_symbol_list[] = { ++ { "os_state", false }, ++ { "__off_os_state2chain", false }, ++ { "__off_os_state2current", false }, ++ { "__off_task2chain", false }, ++ { "__off_task2magic", false }, ++ { "__off_task2stack", false }, ++ { "__off_task2state", false }, ++ { "__off_task2name", false }, ++ { "__val_task_magic", false }, ++ { NULL, false } ++}; ++ ++static void *realloc_preserve(void *ptr, size_t old_size, size_t new_size) ++{ ++ void *new_ptr = malloc(new_size); ++ ++ if (new_ptr) { ++ memcpy(new_ptr, ptr, MIN(old_size, new_size)); ++ free(ptr); ++ } ++ ++ return new_ptr; ++} ++ ++static int rtkernel_add_task(struct rtos *rtos, uint32_t task, uint32_t current_task) ++{ ++ int retval; ++ int new_thread_count = rtos->thread_count + 1; ++ struct thread_detail *new_thread_details = realloc_preserve(rtos->thread_details, ++ rtos->thread_count * sizeof(struct thread_detail), ++ new_thread_count * sizeof(struct thread_detail)); ++ if (!new_thread_details) { ++ LOG_ERROR("Error growing memory to %d threads", new_thread_count); ++ return ERROR_FAIL; ++ } ++ rtos->thread_details = new_thread_details; ++ struct thread_detail *thread = &new_thread_details[rtos->thread_count]; ++ ++ *thread = (struct thread_detail){ .threadid = task, .exists = true }; ++ ++ /* Read the task name */ ++ uint32_t name; ++ retval = target_read_u32(rtos->target, task + rtos->symbols[sym___off_task2name].address, &name); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read task name pointer from target"); ++ return retval; ++ } ++ uint8_t tmp_str[33]; ++ retval = target_read_buffer(rtos->target, name, sizeof(tmp_str) - 1, tmp_str); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Error reading task name from target"); ++ return retval; ++ } ++ tmp_str[sizeof(tmp_str) - 1] = '\0'; ++ LOG_DEBUG("task name at 0x%" PRIx32 ", value \"%s\"", name, tmp_str); ++ ++ if (tmp_str[0] != '\0') ++ thread->thread_name_str = strdup((char *)tmp_str); ++ else ++ thread->thread_name_str = strdup("No Name"); ++ ++ /* Read the task state */ ++ uint16_t state; ++ retval = target_read_u16(rtos->target, task + rtos->symbols[sym___off_task2state].address, &state); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read task state from target"); ++ return retval; ++ } ++ ++ LOG_DEBUG("task state 0x%" PRIx16, state); ++ ++ char state_str[64] = ""; ++ if (state & ST_TT) ++ strcat(state_str, "TT|"); ++ if (task == current_task) { ++ strcat(state_str, "RUN"); ++ } else { ++ if (state & (ST_TT | ST_TT_YIELD)) ++ strcat(state_str, "YIELD"); ++ else if (state & ST_DEAD) ++ strcat(state_str, "DEAD"); ++ else if (state & ST_WAIT) ++ strcat(state_str, "WAIT"); ++ else if (state & ST_SUSPEND) ++ strcat(state_str, "SUSP"); ++ else ++ strcat(state_str, "READY"); ++ } ++ if (state & ST_SEM) ++ strcat(state_str, "|SEM"); ++ if (state & ST_MTX) ++ strcat(state_str, "|MTX"); ++ if (state & ST_SIG) ++ strcat(state_str, "|SIG"); ++ if (state & ST_DLY) ++ strcat(state_str, "|DLY"); ++ if ((state & ST_FLAG) || (state & ST_FLAG_ALL)) ++ strcat(state_str, "|FLAG"); ++ if (state & ST_FLAG_ALL) ++ strcat(state_str, "_ALL"); ++ if (state & ST_MBOX) ++ strcat(state_str, "|MBOX"); ++ if (state & ST_STP) ++ strcat(state_str, "|STP"); ++ ++ thread->extra_info_str = strdup(state_str); ++ ++ rtos->thread_count = new_thread_count; ++ if (task == current_task) ++ rtos->current_thread = task; ++ return ERROR_OK; ++} ++ ++static int rtkernel_verify_task(struct rtos *rtos, uint32_t task) ++{ ++ int retval; ++ uint32_t magic; ++ retval = target_read_u32(rtos->target, task + rtos->symbols[sym___off_task2magic].address, &magic); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read task magic from target"); ++ return retval; ++ } ++ if (magic != rtos->symbols[sym___val_task_magic].address) { ++ LOG_ERROR("Invalid task found (magic=0x%" PRIx32 ")", magic); ++ return ERROR_FAIL; ++ } ++ return retval; ++} ++ ++static int rtkernel_update_threads(struct rtos *rtos) ++{ ++ /* wipe out previous thread details if any */ ++ /* do this first because rtos layer does not check our retval */ ++ rtos_free_threadlist(rtos); ++ rtos->current_thread = 0; ++ ++ if (!rtos->symbols) { ++ LOG_ERROR("No symbols for rt-kernel"); ++ return -3; ++ } ++ ++ /* read the current task */ ++ uint32_t current_task; ++ int retval = target_read_u32(rtos->target, ++ rtos->symbols[sym_os_state].address + rtos->symbols[sym___off_os_state2current].address, ++ ¤t_task); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Error reading current task"); ++ return retval; ++ } ++ LOG_DEBUG("current task is 0x%" PRIx32, current_task); ++ ++ retval = rtkernel_verify_task(rtos, current_task); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Current task is invalid"); ++ return retval; ++ } ++ ++ /* loop through kernel task list */ ++ uint32_t chain = rtos->symbols[sym_os_state].address + rtos->symbols[sym___off_os_state2chain].address; ++ LOG_DEBUG("chain start at 0x%" PRIx32, chain); ++ ++ uint32_t next = chain; ++ for (;;) { ++ retval = target_read_u32(rtos->target, next, &next); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read rt-kernel data structure from target"); ++ return retval; ++ } ++ LOG_DEBUG("next entry at 0x%" PRIx32, next); ++ if (next == chain) { ++ LOG_DEBUG("end of chain detected"); ++ break; ++ } ++ uint32_t task = next - rtos->symbols[sym___off_task2chain].address; ++ LOG_DEBUG("found task at 0x%" PRIx32, task); ++ ++ retval = rtkernel_verify_task(rtos, task); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Invalid task found"); ++ return retval; ++ } ++ ++ retval = rtkernel_add_task(rtos, task, current_task); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not add task to rtos system"); ++ return retval; ++ } ++ } ++ return ERROR_OK; ++} ++ ++static int rtkernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, ++ struct rtos_reg **reg_list, int *num_regs) ++{ ++ uint32_t stack_ptr = 0; ++ ++ if (!rtos) ++ return -1; ++ ++ if (thread_id == 0) ++ return -2; ++ ++ if (!rtos->rtos_specific_params) ++ return -1; ++ ++ const struct rtkernel_params *param = rtos->rtos_specific_params; ++ ++ /* Read the stack pointer */ ++ int retval = target_read_u32(rtos->target, thread_id + rtos->symbols[sym___off_task2stack].address, &stack_ptr); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Error reading stack pointer from rtkernel thread"); ++ return retval; ++ } ++ LOG_DEBUG("stack pointer at 0x%" PRIx64 ", value 0x%" PRIx32, ++ thread_id + rtos->symbols[sym___off_task2stack].address, ++ stack_ptr); ++ ++ /* Adjust stack pointer to ignore non-standard BASEPRI register stacking */ ++ stack_ptr += 4; ++ ++ /* Check for armv7m with *enabled* FPU, i.e. a Cortex M4F */ ++ bool cm4_fpu_enabled = false; ++ struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target); ++ if (is_armv7m(armv7m_target)) { ++ if (armv7m_target->fp_feature != FP_NONE) { ++ /* Found ARM v7m target which includes a FPU */ ++ uint32_t cpacr; ++ ++ retval = target_read_u32(rtos->target, FPU_CPACR, &cpacr); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read CPACR register to check FPU state"); ++ return -1; ++ } ++ ++ /* Check if CP10 and CP11 are set to full access. */ ++ if (cpacr & 0x00F00000) { ++ /* Found target with enabled FPU */ ++ cm4_fpu_enabled = true; ++ } ++ } ++ } ++ ++ if (!cm4_fpu_enabled) { ++ LOG_DEBUG("cm3 stacking"); ++ return rtos_generic_stack_read(rtos->target, param->stacking_info_cm3, stack_ptr, reg_list, num_regs); ++ } ++ ++ /* Read the LR to decide between stacking with or without FPU */ ++ uint32_t lr_svc; ++ retval = target_read_u32(rtos->target, stack_ptr + 0x20, &lr_svc); ++ if (retval != ERROR_OK) { ++ LOG_OUTPUT("Error reading stack frame from rtkernel thread\r\n"); ++ return retval; ++ } ++ ++ if ((lr_svc & 0x10) == 0) { ++ LOG_DEBUG("cm4f_fpu stacking"); ++ return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f_fpu, stack_ptr, reg_list, num_regs); ++ } ++ ++ LOG_DEBUG("cm4f stacking"); ++ return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f, stack_ptr, reg_list, num_regs); ++} ++ ++static int rtkernel_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]) ++{ ++ *symbol_list = calloc(ARRAY_SIZE(rtkernel_symbol_list), sizeof(struct symbol_table_elem)); ++ if (!*symbol_list) ++ return ERROR_FAIL; ++ ++ for (size_t i = 0; i < ARRAY_SIZE(rtkernel_symbol_list); i++) { ++ (*symbol_list)[i].symbol_name = rtkernel_symbol_list[i].name; ++ (*symbol_list)[i].optional = rtkernel_symbol_list[i].optional; ++ } ++ ++ return ERROR_OK; ++} ++ ++static bool rtkernel_detect_rtos(struct target *target) ++{ ++ return (target->rtos->symbols) && ++ (target->rtos->symbols[sym___off_os_state2chain].address != 0); ++} ++ ++static int rtkernel_create(struct target *target) ++{ ++ for (size_t i = 0; i < ARRAY_SIZE(rtkernel_params_list); i++) { ++ if (strcmp(rtkernel_params_list[i].target_name, target->type->name) == 0) { ++ target->rtos->rtos_specific_params = (void *)&rtkernel_params_list[i]; ++ return 0; ++ } ++ } ++ ++ LOG_ERROR("Could not find target in rt-kernel compatibility list"); ++ return -1; ++} ++ ++const struct rtos_type rtkernel_rtos = { ++ .name = "rtkernel", ++ ++ .detect_rtos = rtkernel_detect_rtos, ++ .create = rtkernel_create, ++ .update_threads = rtkernel_update_threads, ++ .get_thread_reg_list = rtkernel_get_thread_reg_list, ++ .get_symbol_list_to_lookup = rtkernel_get_symbol_list_to_lookup, ++}; +diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c +index dfa158d01..bcd556a7b 100644 +--- a/src/rtos/rtos.c ++++ b/src/rtos/rtos.c +@@ -29,6 +29,7 @@ extern struct rtos_type nuttx_rtos; + extern struct rtos_type hwthread_rtos; + extern struct rtos_type riot_rtos; + extern struct rtos_type zephyr_rtos; ++extern struct rtos_type rtkernel_rtos; + + static struct rtos_type *rtos_types[] = { + &threadx_rtos, +@@ -43,6 +44,7 @@ static struct rtos_type *rtos_types[] = { + &nuttx_rtos, + &riot_rtos, + &zephyr_rtos, ++ &rtkernel_rtos, + /* keep this as last, as it always matches with rtos auto */ + &hwthread_rtos, + NULL diff --git a/meta-oe/recipes-devtools/openocd/openocd/0051-rtos-Fix-constness-of-struct-rtos_type.patch b/meta-oe/recipes-devtools/openocd/openocd/0051-rtos-Fix-constness-of-struct-rtos_type.patch new file mode 100644 index 000000000..7d6ea6709 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0051-rtos-Fix-constness-of-struct-rtos_type.patch @@ -0,0 +1,168 @@ +From d032e7ec8c2978feda5df2ca7c4ddbcaec2fcbf5 Mon Sep 17 00:00:00 2001 +From: Andreas Fritiofson +Date: Mon, 8 Nov 2021 19:35:27 +0100 +Subject: [PATCH] rtos: Fix constness of struct rtos_type + +Change-Id: Iaa89f2ff4036c23f944ffb4f37fe0c7afaf5069b +Signed-off-by: Andreas Fritiofson +Reviewed-on: https://review.openocd.org/c/openocd/+/6680 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/rtos/FreeRTOS.c | 2 +- + src/rtos/chibios.c | 2 +- + src/rtos/embKernel.c | 2 +- + src/rtos/mqx.c | 2 +- + src/rtos/nuttx.c | 2 +- + src/rtos/rtos.c | 38 +++++++++++++++++++------------------- + src/rtos/zephyr.c | 2 +- + 7 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c +index 945c4b875..070275f2c 100644 +--- a/src/rtos/FreeRTOS.c ++++ b/src/rtos/FreeRTOS.c +@@ -80,7 +80,7 @@ static int freertos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + struct rtos_reg **reg_list, int *num_regs); + static int freertos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]); + +-struct rtos_type freertos_rtos = { ++const struct rtos_type freertos_rtos = { + .name = "FreeRTOS", + + .detect_rtos = freertos_detect_rtos, +diff --git a/src/rtos/chibios.c b/src/rtos/chibios.c +index 8319cc883..68fe8a14c 100644 +--- a/src/rtos/chibios.c ++++ b/src/rtos/chibios.c +@@ -97,7 +97,7 @@ static int chibios_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + struct rtos_reg **reg_list, int *num_regs); + static int chibios_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]); + +-struct rtos_type chibios_rtos = { ++const struct rtos_type chibios_rtos = { + .name = "chibios", + + .detect_rtos = chibios_detect_rtos, +diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c +index c1b5723fc..a03b039e0 100644 +--- a/src/rtos/embKernel.c ++++ b/src/rtos/embKernel.c +@@ -27,7 +27,7 @@ static int embkernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + struct rtos_reg **reg_list, int *num_regs); + static int embkernel_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]); + +-struct rtos_type embkernel_rtos = { ++const struct rtos_type embkernel_rtos = { + .name = "embKernel", + .detect_rtos = embkernel_detect_rtos, + .create = embkernel_create, +diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c +index 8d483ed3b..d9b694282 100644 +--- a/src/rtos/mqx.c ++++ b/src/rtos/mqx.c +@@ -498,7 +498,7 @@ static int mqx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[] + return ERROR_OK; + } + +-struct rtos_type mqx_rtos = { ++const struct rtos_type mqx_rtos = { + .name = "mqx", + .detect_rtos = mqx_detect_rtos, + .create = mqx_create, +diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c +index 993ff84bd..78271181e 100644 +--- a/src/rtos/nuttx.c ++++ b/src/rtos/nuttx.c +@@ -324,7 +324,7 @@ static int nuttx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list + return 0; + } + +-struct rtos_type nuttx_rtos = { ++const struct rtos_type nuttx_rtos = { + .name = "nuttx", + .detect_rtos = nuttx_detect_rtos, + .create = nuttx_create, +diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c +index bcd556a7b..f1e8956a3 100644 +--- a/src/rtos/rtos.c ++++ b/src/rtos/rtos.c +@@ -16,22 +16,22 @@ + #include "server/gdb_server.h" + + /* RTOSs */ +-extern struct rtos_type freertos_rtos; +-extern struct rtos_type threadx_rtos; +-extern struct rtos_type ecos_rtos; +-extern struct rtos_type linux_rtos; +-extern struct rtos_type chibios_rtos; +-extern struct rtos_type chromium_ec_rtos; +-extern struct rtos_type embkernel_rtos; +-extern struct rtos_type mqx_rtos; +-extern struct rtos_type ucos_iii_rtos; +-extern struct rtos_type nuttx_rtos; +-extern struct rtos_type hwthread_rtos; +-extern struct rtos_type riot_rtos; +-extern struct rtos_type zephyr_rtos; +-extern struct rtos_type rtkernel_rtos; +- +-static struct rtos_type *rtos_types[] = { ++extern const struct rtos_type freertos_rtos; ++extern const struct rtos_type threadx_rtos; ++extern const struct rtos_type ecos_rtos; ++extern const struct rtos_type linux_rtos; ++extern const struct rtos_type chibios_rtos; ++extern const struct rtos_type chromium_ec_rtos; ++extern const struct rtos_type embkernel_rtos; ++extern const struct rtos_type mqx_rtos; ++extern const struct rtos_type ucos_iii_rtos; ++extern const struct rtos_type nuttx_rtos; ++extern const struct rtos_type hwthread_rtos; ++extern const struct rtos_type riot_rtos; ++extern const struct rtos_type zephyr_rtos; ++extern const struct rtos_type rtkernel_rtos; ++ ++static const struct rtos_type *rtos_types[] = { + &threadx_rtos, + &freertos_rtos, + &ecos_rtos, +@@ -70,7 +70,7 @@ static int rtos_target_for_threadid(struct connection *connection, int64_t threa + return ERROR_OK; + } + +-static int os_alloc(struct target *target, struct rtos_type *ostype) ++static int os_alloc(struct target *target, const struct rtos_type *ostype) + { + struct rtos *os = target->rtos = calloc(1, sizeof(struct rtos)); + +@@ -100,7 +100,7 @@ static void os_free(struct target *target) + target->rtos = NULL; + } + +-static int os_alloc_create(struct target *target, struct rtos_type *ostype) ++static int os_alloc_create(struct target *target, const struct rtos_type *ostype) + { + int ret = os_alloc(target, ostype); + +@@ -683,7 +683,7 @@ int rtos_generic_stack_read(struct target *target, + static int rtos_try_next(struct target *target) + { + struct rtos *os = target->rtos; +- struct rtos_type **type = rtos_types; ++ const struct rtos_type **type = rtos_types; + + if (!os) + return 0; +diff --git a/src/rtos/zephyr.c b/src/rtos/zephyr.c +index b00b4b341..934a8dd1c 100644 +--- a/src/rtos/zephyr.c ++++ b/src/rtos/zephyr.c +@@ -785,7 +785,7 @@ static int zephyr_get_symbol_list_to_lookup(struct symbol_table_elem **symbol_li + return ERROR_OK; + } + +-struct rtos_type zephyr_rtos = { ++const struct rtos_type zephyr_rtos = { + .name = "Zephyr", + + .detect_rtos = zephyr_detect_rtos, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0052-jtag-drivers-openjtag-fix-annoying-num_cycles-16-war.patch b/meta-oe/recipes-devtools/openocd/openocd/0052-jtag-drivers-openjtag-fix-annoying-num_cycles-16-war.patch new file mode 100644 index 000000000..c6619e88b --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0052-jtag-drivers-openjtag-fix-annoying-num_cycles-16-war.patch @@ -0,0 +1,51 @@ +From 20285b91008106c9fa966cea3269c6f6a81e539a Mon Sep 17 00:00:00 2001 +From: N S +Date: Fri, 23 Dec 2022 16:59:18 -0800 +Subject: [PATCH] jtag/drivers/openjtag: fix annoying num_cycles > 16 warning + +The OpenJTAG driver logs "num_cycles > 16 on run test" warning +whenever the JTAG_RUNTEST operation cycle count is larger than 16. + +Instead of logging the warning and only running the first 16 TCLK +cycles, remove the warning and queue up multiple operations of up +to 16 cycles each. + +Signed-off-by: N S +Change-Id: Id405fa802ff1cf3db7a21e76bd6df0c2d3a0fe61 +Reviewed-on: https://review.openocd.org/c/openocd/+/7420 +Tested-by: jenkins +Reviewed-by: Jonathan McDowell +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/openjtag.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c +index 6be950718..12ea46330 100644 +--- a/src/jtag/drivers/openjtag.c ++++ b/src/jtag/drivers/openjtag.c +@@ -742,16 +742,18 @@ static void openjtag_execute_runtest(struct jtag_command *cmd) + tap_set_state(TAP_IDLE); + } + +- if (cmd->cmd.runtest->num_cycles > 16) +- LOG_WARNING("num_cycles > 16 on run test"); +- + if (openjtag_variant != OPENJTAG_VARIANT_CY7C65215 || + cmd->cmd.runtest->num_cycles) { + uint8_t command; +- command = 7; +- command |= ((cmd->cmd.runtest->num_cycles - 1) & 0x0F) << 4; ++ int cycles = cmd->cmd.runtest->num_cycles; + +- openjtag_add_byte(command); ++ do { ++ command = 7; ++ command |= (((cycles > 16 ? 16 : cycles) - 1) & 0x0F) << 4; ++ ++ openjtag_add_byte(command); ++ cycles -= 16; ++ } while (cycles > 0); + } + + tap_set_end_state(end_state); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0053-jtag-drivers-bitbang-avoid-mostly-harmless-glitch-on.patch b/meta-oe/recipes-devtools/openocd/openocd/0053-jtag-drivers-bitbang-avoid-mostly-harmless-glitch-on.patch new file mode 100644 index 000000000..f92c29133 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0053-jtag-drivers-bitbang-avoid-mostly-harmless-glitch-on.patch @@ -0,0 +1,68 @@ +From 148bc7e2151740527b4ca67d0a7c7c9f01725981 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Fri, 14 Oct 2022 09:19:29 +0200 +Subject: [PATCH] jtag/drivers/bitbang: avoid mostly harmless glitch on SWDIO + +bitbang_swd_exchange(rnw=true,...) calls bitbang_interface->swd_write() +with swdio clamped to 0. +bitbang_swd_write_reg() reads 1 turnaround bit, 3 ack bits +and 1 turnaround by one call to bitbang_swd_exchange() +and then switches SWDIO to output. +AFAIK all bitbang interfaces switch SWDIO GPIO direction immediately +in bitbang_interface->swdio_drive(). +The GPIO now drives SWDIO line to the value stored in the output register +which is always zero from previous bitbang_swd_exchange(rnw=true,...). +In case the following data bit (bit 0) is 1 we can observe a glitch +on SWDIO: + _____ out 1 ____ +HiZ/pull-up ----\ / + \ / + \______ out 0 ______/ + swdio_drive(true) swd_write(0,1) + +The glitch fortunately takes place far enough from SWCLK rising edge +where SWDIO is sampled by the target, so I believe it is harmless +except some corner cases where the reflected wave is delayed on long +line. + +Anyway keeping electrical signals glitch free is a good practice. +To keep performance penalty minimal, pre-write the first data +bit to SWDIO GPIO output buffer while clocking the turnaround bit. +Following swdio_drive(true) outputs the pre-written value +and the same value is rewritten by the next swd_write() +instead of glitching SWDIO. + +Change-Id: I72ea9c0b2fae57e8ff5aa616859182c67abc924f +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7260 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/bitbang.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c +index 2ab0a2a76..665dbf329 100644 +--- a/src/jtag/drivers/bitbang.c ++++ b/src/jtag/drivers/bitbang.c +@@ -525,7 +525,19 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay + bitbang_swd_exchange(false, &cmd, 0, 8); + + bitbang_interface->swdio_drive(false); +- bitbang_swd_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 1); ++ bitbang_swd_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3); ++ ++ /* Avoid a glitch on SWDIO when changing the direction to output. ++ * To keep performance penalty minimal, pre-write the first data ++ * bit to SWDIO GPIO output buffer while clocking the turnaround bit. ++ * Following swdio_drive(true) outputs the pre-written value ++ * and the same value is rewritten by the next swd_write() ++ * instead of glitching SWDIO ++ * HiZ/pull-up --------------> 0 -------------> 1 ++ * swdio_drive(true) swd_write(0,1) ++ * in case of data bit 0 = 1 ++ */ ++ bitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 1); + bitbang_interface->swdio_drive(true); + bitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1); + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0054-jtag-drivers-bcm2835gpio-use-rounding-in-delay-math.patch b/meta-oe/recipes-devtools/openocd/openocd/0054-jtag-drivers-bcm2835gpio-use-rounding-in-delay-math.patch new file mode 100644 index 000000000..a9a9d237a --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0054-jtag-drivers-bcm2835gpio-use-rounding-in-delay-math.patch @@ -0,0 +1,50 @@ +From b4dd8dbc37daf073bf6481fdc7f0f9d7f2e96809 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Thu, 13 Oct 2022 16:46:31 +0200 +Subject: [PATCH] jtag/drivers/bcm2835gpio: use rounding in delay math + +After setting adapter speed to some values, the driver +shows the real speed little bit higher. +Although it does not impose a problem from technical point +of view because the difference is smaller than usual speed error, +it looks at least strange to the user. The documentation reads +that real frequency should be same or lower than requested. + +Use proper rounding in speed -> delay and delay -> speed +conversions. + +Change-Id: I1831112cc58681875548d2aeb688391fb79fa37f +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7261 +Tested-by: jenkins +Reviewed-by: Jonathan Bell +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/bcm2835gpio.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c +index 5aa1a99e4..320baba09 100644 +--- a/src/jtag/drivers/bcm2835gpio.c ++++ b/src/jtag/drivers/bcm2835gpio.c +@@ -264,7 +264,8 @@ static int bcm2835gpio_khz(int khz, int *jtag_speed) + LOG_DEBUG("BCM2835 GPIO: RCLK not supported"); + return ERROR_FAIL; + } +- *jtag_speed = speed_coeff/khz - speed_offset; ++ *jtag_speed = DIV_ROUND_UP(speed_coeff, khz) - speed_offset; ++ LOG_DEBUG("jtag_delay %d", *jtag_speed); + if (*jtag_speed < 0) + *jtag_speed = 0; + return ERROR_OK; +@@ -272,7 +273,9 @@ static int bcm2835gpio_khz(int khz, int *jtag_speed) + + static int bcm2835gpio_speed_div(int speed, int *khz) + { +- *khz = speed_coeff/(speed + speed_offset); ++ int divisor = speed + speed_offset; ++ /* divide with roundig to the closest */ ++ *khz = (speed_coeff + divisor / 2) / divisor; + return ERROR_OK; + } + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0055-jtag-drivers-bcm2835gpio-refactor-delays-to-inline-f.patch b/meta-oe/recipes-devtools/openocd/openocd/0055-jtag-drivers-bcm2835gpio-refactor-delays-to-inline-f.patch new file mode 100644 index 000000000..7e24aeb5d --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0055-jtag-drivers-bcm2835gpio-refactor-delays-to-inline-f.patch @@ -0,0 +1,63 @@ +From 2dde7e914b429ffa5bc56faa20fb474ca451412e Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Thu, 13 Oct 2022 22:33:12 +0200 +Subject: [PATCH] jtag/drivers/bcm2835gpio: refactor delays to inline function + +No functional change, the delay is unchanged. + +Change-Id: I5b5e837d741ac01fc573657357c5fe61ad901319 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7262 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/bcm2835gpio.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c +index 320baba09..635d9a5ff 100644 +--- a/src/jtag/drivers/bcm2835gpio.c ++++ b/src/jtag/drivers/bcm2835gpio.c +@@ -66,6 +66,12 @@ static inline void bcm2835_gpio_synchronize(void) + __sync_synchronize(); + } + ++static inline void bcm2835_delay(void) ++{ ++ for (unsigned int i = 0; i < jtag_delay; i++) ++ asm volatile (""); ++} ++ + static bool is_gpio_config_valid(enum adapter_gpio_config_index idx) + { + /* Only chip 0 is supported, accept unset value (-1) too */ +@@ -178,8 +184,7 @@ static int bcm2835gpio_write(int tck, int tms, int tdi) + GPIO_CLR = clear; + bcm2835_gpio_synchronize(); + +- for (unsigned int i = 0; i < jtag_delay; i++) +- asm volatile (""); ++ bcm2835_delay(); + + return ERROR_OK; + } +@@ -199,8 +204,7 @@ static int bcm2835gpio_swd_write_fast(int swclk, int swdio) + GPIO_CLR = clear; + bcm2835_gpio_synchronize(); + +- for (unsigned int i = 0; i < jtag_delay; i++) +- asm volatile (""); ++ bcm2835_delay(); + + return ERROR_OK; + } +@@ -211,8 +215,7 @@ static int bcm2835gpio_swd_write_generic(int swclk, int swdio) + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio); + set_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */ + +- for (unsigned int i = 0; i < jtag_delay; ++i) +- asm volatile (""); ++ bcm2835_delay(); + + return ERROR_OK; + } diff --git a/meta-oe/recipes-devtools/openocd/openocd/0056-tcl-interface-universal-config-for-all-Raspberry-Pi-.patch b/meta-oe/recipes-devtools/openocd/openocd/0056-tcl-interface-universal-config-for-all-Raspberry-Pi-.patch new file mode 100644 index 000000000..52a435c80 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0056-tcl-interface-universal-config-for-all-Raspberry-Pi-.patch @@ -0,0 +1,242 @@ +From bec6c0eb094fb7ca1752688118f41193dc83e026 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Fri, 14 Oct 2022 11:16:58 +0200 +Subject: [PATCH] tcl/interface: universal config for all Raspberry Pi models + +Speed calibration coeffs are computed from cpufreq/scaling_max_freq +and from the device-tree compatibility information. + +Raspberry Pi linux offers /dev/gpiomem for non-root access +to the GPIO registers since ~2016. +Do not configure 'bcm2835gpio peripheral_base' as it is necessary +only if /dev/mem is used - it requires running OpenOCD as root +- it's a security risk so it should be avoided. + +The configuration of the GPIO connector (40-pin header) +is factored out and ready to use in interface configuration +for other driver (e.g. linux gpiod). + +Mark raspberrypi2-native.cfg as deprecated and redirect +it to raspberrypi-native.cfg + +Change-Id: Icce856fb660b45374e94174da279feb51f529908 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7264 +Tested-by: jenkins +Reviewed-by: Jonathan Bell +Reviewed-by: Antonio Borneo +--- + tcl/interface/raspberrypi-gpio-connector.cfg | 42 +++++++++ + tcl/interface/raspberrypi-native.cfg | 91 +++++++++++++------- + tcl/interface/raspberrypi2-native.cfg | 44 +--------- + 3 files changed, 104 insertions(+), 73 deletions(-) + create mode 100644 tcl/interface/raspberrypi-gpio-connector.cfg + +diff --git a/tcl/interface/raspberrypi-gpio-connector.cfg b/tcl/interface/raspberrypi-gpio-connector.cfg +new file mode 100644 +index 000000000..eff73fc92 +--- /dev/null ++++ b/tcl/interface/raspberrypi-gpio-connector.cfg +@@ -0,0 +1,42 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++# ++# Config for Raspberry Pi GPIO header ++# ++# This is best used with a fast enough buffer but also ++# is suitable for direct connection if the target voltage ++# matches RPi's 3.3V and the cable is short enough. ++# ++# Do not forget the GND connection, e.g. pin 20 of the GPIO header. ++# ++ ++# GPIO 25 (pin 22) previously used for TMS/SWDIO is pulled-down by default. ++# The JTAG/SWD specification requires pull-up at the target board ++# for either signal. Connecting the signal pulled-up on the target ++# to the pull-down on the adapter is not a good idea. ++# GPIO 8 is pulled-up by default. ++echo "Warn : TMS/SWDIO moved to GPIO 8 (pin 24). Check the wiring please!" ++ ++# Each of the JTAG lines need a gpio number set: tck tms tdi tdo ++# Header pin numbers: 23 24 19 21 ++adapter gpio tck -chip 0 11 ++adapter gpio tms -chip 0 8 ++adapter gpio tdi -chip 0 10 ++adapter gpio tdo -chip 0 9 ++ ++# Each of the SWD lines need a gpio number set: swclk swdio ++# Header pin numbers: 23 24 ++adapter gpio swclk -chip 0 11 ++adapter gpio swdio -chip 0 8 ++ ++# If you define trst or srst, use appropriate reset_config ++# Header pin numbers: TRST - 26, SRST - 18 ++ ++# adapter gpio trst -chip 0 7 ++# reset_config trst_only ++ ++# adapter gpio srst -chip 0 24 ++# reset_config srst_only srst_push_pull ++ ++# or if you have both connected, ++# reset_config trst_and_srst srst_push_pull +diff --git a/tcl/interface/raspberrypi-native.cfg b/tcl/interface/raspberrypi-native.cfg +index 02a356350..95426c226 100644 +--- a/tcl/interface/raspberrypi-native.cfg ++++ b/tcl/interface/raspberrypi-native.cfg +@@ -1,44 +1,71 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + +-# +-# Config for using Raspberry Pi's expansion header +-# +-# This is best used with a fast enough buffer but also +-# is suitable for direct connection if the target voltage +-# matches RPi's 3.3V and the cable is short enough. +-# +-# Do not forget the GND connection, pin 6 of the expansion header. +-# ++# Config for Raspberry Pi used as a bitbang adapter. ++# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html ++ ++# Supports all models with 40-pin or 26-pin GPIO connector up to Raspberry Pi 4 B ++# also supports Raspberry Pi Zero, Zero W and Zero 2 W. ++ ++# Adapter speed calibration is computed from cpufreq/scaling_max_freq. ++# Adjusts automatically if CPU is overclocked. + + adapter driver bcm2835gpio + +-bcm2835gpio peripheral_base 0x20000000 ++proc read_file { name } { ++ if {[catch {open $name r} fd]} { ++ return "" ++ } ++ set result [read $fd] ++ close $fd ++ return $result ++} + +-# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET +-# These depend on system clock, calibrated for stock 700MHz +-# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET +-bcm2835gpio speed_coeffs 113714 28 ++proc measure_clock {} { ++ set result [exec vcgencmd measure_clock arm] ++ set clock_hz [lindex [split $result "="] 1] ++ expr { $clock_hz / 1000 } ++} ++ ++proc get_max_cpu_clock { default } { ++ set clock [read_file /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq] ++ if { $clock > 100000 } { ++ return $clock ++ } + +-# Each of the JTAG lines need a gpio number set: tck tms tdi tdo +-# Header pin numbers: 23 22 19 21 +-adapter gpio tck -chip 0 11 +-adapter gpio tms -chip 0 25 +-adapter gpio tdi -chip 0 10 +-adapter gpio tdo -chip 0 9 ++ # cpufreq not available. As the last resort try Broadcom's proprietary utility ++ if {![catch measure_clock clock] && $clock > 100000} { ++ return $clock ++ } + +-# Each of the SWD lines need a gpio number set: swclk swdio +-# Header pin numbers: 23 22 +-adapter gpio swclk -chip 0 11 +-adapter gpio swdio -chip 0 25 ++ echo "WARNING: Host CPU clock unknown." ++ echo "WARNING: Using the highest possible value $default kHz as a safe default." ++ echo "WARNING: Expect JTAG/SWD clock significantly slower than requested." + +-# If you define trst or srst, use appropriate reset_config +-# Header pin numbers: TRST - 26, SRST - 18 ++ return $default ++} + +-# adapter gpio trst -chip 0 7 +-# reset_config trst_only ++set compat [read_file /proc/device-tree/compatible] ++set clocks_per_timing_loop 4 + +-# adapter gpio srst -chip 0 24 +-# reset_config srst_only srst_push_pull ++if {[string match *bcm2711* $compat]} { ++ set speed_offset 52 ++} elseif {[string match *bcm2837* $compat] || [string match *bcm2710* $compat]} { ++ set speed_offset 34 ++} elseif {[string match *bcm2836* $compat] || [string match *bcm2709* $compat]} { ++ set speed_offset 36 ++} elseif {[string match *bcm2835* $compat] || [string match *bcm2708* $compat]} { ++ set clocks_per_timing_loop 6 ++ set speed_offset 32 ++} else { ++ set speed_offset 32 ++ echo "WARNING: Unknown type of the host SoC. Expect JTAG/SWD clock slower than requested." ++} ++ ++set clock [get_max_cpu_clock 2000000] ++set speed_coeff [expr { $clock / $clocks_per_timing_loop }] ++ ++# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET ++# The coefficients depend on system clock and CPU frequency scaling. ++bcm2835gpio speed_coeffs $speed_coeff $speed_offset + +-# or if you have both connected, +-# reset_config trst_and_srst srst_push_pull ++source raspberrypi-gpio-connector.cfg +diff --git a/tcl/interface/raspberrypi2-native.cfg b/tcl/interface/raspberrypi2-native.cfg +index d5edded0f..fe9186f23 100644 +--- a/tcl/interface/raspberrypi2-native.cfg ++++ b/tcl/interface/raspberrypi2-native.cfg +@@ -1,44 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + +-# +-# Config for using Raspberry Pi's expansion header +-# +-# This is best used with a fast enough buffer but also +-# is suitable for direct connection if the target voltage +-# matches RPi's 3.3V and the cable is short enough. +-# +-# Do not forget the GND connection, pin 6 of the expansion header. +-# ++echo "WARNING: interface/raspberrypi2-native.cfg is deprecated." ++echo "WARNING: Please use interface/raspberrypi-native.cfg for all Raspberry Pi models." + +-adapter driver bcm2835gpio +- +-bcm2835gpio peripheral_base 0x3F000000 +- +-# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET +-# These depend on system clock, calibrated for scaling_max_freq 900MHz +-# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET +-bcm2835gpio speed_coeffs 225000 36 +- +-# Each of the JTAG lines need a gpio number set: tck tms tdi tdo +-# Header pin numbers: 23 22 19 21 +-adapter gpio tck -chip 0 11 +-adapter gpio tms -chip 0 25 +-adapter gpio tdi -chip 0 10 +-adapter gpio tdo -chip 0 9 +- +-# Each of the SWD lines need a gpio number set: swclk swdio +-# Header pin numbers: 23 22 +-adapter gpio swclk -chip 0 11 +-adapter gpio swdio -chip 0 25 +- +-# If you define trst or srst, use appropriate reset_config +-# Header pin numbers: TRST - 26, SRST - 18 +- +-# adapter gpio trst -chip 0 7 +-# reset_config trst_only +- +-# adapter gpio srst -chip 0 24 +-# reset_config srst_only srst_push_pull +- +-# or if you have both connected, +-# reset_config trst_and_srst srst_push_pull ++source [find interface/raspberrypi-native.cfg] diff --git a/meta-oe/recipes-devtools/openocd/openocd/0057-rtos-remove-config.h-includes-from-stackings-headers.patch b/meta-oe/recipes-devtools/openocd/openocd/0057-rtos-remove-config.h-includes-from-stackings-headers.patch new file mode 100644 index 000000000..ae529b18c --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0057-rtos-remove-config.h-includes-from-stackings-headers.patch @@ -0,0 +1,237 @@ +From 227577ba7616ca129790090e1101b503f7b9cdb7 Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Sat, 21 Jan 2023 12:46:33 +0100 +Subject: [PATCH] rtos: remove config.h includes from stackings headers + +And add its own header to the rtos_xxx_stackings.c + +Signed-off-by: Erhan Kurubas +Change-Id: I084130fde7ee8645129a7cf60bb7bf59448e2f39 +Reviewed-on: https://review.openocd.org/c/openocd/+/7441 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/rtos/rtos_chibios_stackings.c | 1 + + src/rtos/rtos_chibios_stackings.h | 4 ---- + src/rtos/rtos_ecos_stackings.c | 3 ++- + src/rtos/rtos_ecos_stackings.h | 4 ---- + src/rtos/rtos_embkernel_stackings.c | 1 + + src/rtos/rtos_embkernel_stackings.h | 4 ---- + src/rtos/rtos_mqx_stackings.c | 2 +- + src/rtos/rtos_mqx_stackings.h | 4 ---- + src/rtos/rtos_riot_stackings.c | 1 + + src/rtos/rtos_riot_stackings.h | 5 ----- + src/rtos/rtos_standard_stackings.c | 1 + + src/rtos/rtos_standard_stackings.h | 4 ---- + src/rtos/rtos_ucos_iii_stackings.c | 10 +++++----- + src/rtos/rtos_ucos_iii_stackings.h | 6 +----- + 14 files changed, 13 insertions(+), 37 deletions(-) + +diff --git a/src/rtos/rtos_chibios_stackings.c b/src/rtos/rtos_chibios_stackings.c +index e2fe0a27f..c0816ac3c 100644 +--- a/src/rtos/rtos_chibios_stackings.c ++++ b/src/rtos/rtos_chibios_stackings.c +@@ -14,6 +14,7 @@ + + #include "rtos.h" + #include "target/armv7m.h" ++#include "rtos_chibios_stackings.h" + + static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets[ARMV7M_NUM_CORE_REGS] = { + { ARMV7M_R0, -1, 32 }, /* r0 */ +diff --git a/src/rtos/rtos_chibios_stackings.h b/src/rtos/rtos_chibios_stackings.h +index 23ad44ae3..e909451e2 100644 +--- a/src/rtos/rtos_chibios_stackings.h ++++ b/src/rtos/rtos_chibios_stackings.h +@@ -8,10 +8,6 @@ + #ifndef OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H + #define OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- + #include "rtos.h" + + extern const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking; +diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c +index 86e176507..cae271270 100644 +--- a/src/rtos/rtos_ecos_stackings.c ++++ b/src/rtos/rtos_ecos_stackings.c +@@ -5,8 +5,9 @@ + #endif + + #include "rtos.h" +-#include "rtos_standard_stackings.h" + #include "target/armv7m.h" ++#include "rtos_standard_stackings.h" ++#include "rtos_ecos_stackings.h" + + /* For Cortex-M eCos applications the actual thread context register layout can + * be different between active threads of an application depending on whether +diff --git a/src/rtos/rtos_ecos_stackings.h b/src/rtos/rtos_ecos_stackings.h +index 0375e2d1c..a6bcf1acb 100644 +--- a/src/rtos/rtos_ecos_stackings.h ++++ b/src/rtos/rtos_ecos_stackings.h +@@ -3,10 +3,6 @@ + #ifndef OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H + #define OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- + #include "rtos.h" + + extern const struct rtos_register_stacking rtos_ecos_cortex_m3_stacking; +diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c +index 809b622e0..b98628a13 100644 +--- a/src/rtos/rtos_embkernel_stackings.c ++++ b/src/rtos/rtos_embkernel_stackings.c +@@ -12,6 +12,7 @@ + #include "rtos.h" + #include "target/armv7m.h" + #include "rtos_standard_stackings.h" ++#include "rtos_embkernel_stackings.h" + + static const struct stack_register_offset rtos_embkernel_cortex_m_stack_offsets[ARMV7M_NUM_CORE_REGS] = { + { ARMV7M_R0, 0x24, 32 }, /* r0 */ +diff --git a/src/rtos/rtos_embkernel_stackings.h b/src/rtos/rtos_embkernel_stackings.h +index 972bce66d..87bd0e73b 100644 +--- a/src/rtos/rtos_embkernel_stackings.h ++++ b/src/rtos/rtos_embkernel_stackings.h +@@ -8,10 +8,6 @@ + #ifndef OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H + #define OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- + #include "rtos.h" + + extern const struct rtos_register_stacking rtos_embkernel_cortex_m_stacking; +diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c +index 8c8fd2053..5ab743bf3 100644 +--- a/src/rtos/rtos_mqx_stackings.c ++++ b/src/rtos/rtos_mqx_stackings.c +@@ -11,7 +11,7 @@ + + #include "rtos.h" + #include "target/armv7m.h" +- ++#include "rtos_mqx_stackings.h" + + /* + * standard exception stack +diff --git a/src/rtos/rtos_mqx_stackings.h b/src/rtos/rtos_mqx_stackings.h +index f86c05a40..faa741de6 100644 +--- a/src/rtos/rtos_mqx_stackings.h ++++ b/src/rtos/rtos_mqx_stackings.h +@@ -8,10 +8,6 @@ + #ifndef OPENOCD_RTOS_RTOS_MQX_STACKINGS_H + #define OPENOCD_RTOS_RTOS_MQX_STACKINGS_H + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- + #include "rtos.h" + + extern const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking; +diff --git a/src/rtos/rtos_riot_stackings.c b/src/rtos/rtos_riot_stackings.c +index e717e8cfe..e46762168 100644 +--- a/src/rtos/rtos_riot_stackings.c ++++ b/src/rtos/rtos_riot_stackings.c +@@ -12,6 +12,7 @@ + #include "rtos.h" + #include "target/armv7m.h" + #include "rtos_standard_stackings.h" ++#include "rtos_riot_stackings.h" + + /* This works for the M0 and M34 stackings as xPSR is in a fixed + * location +diff --git a/src/rtos/rtos_riot_stackings.h b/src/rtos/rtos_riot_stackings.h +index 3b6c5f41c..ebd533756 100644 +--- a/src/rtos/rtos_riot_stackings.h ++++ b/src/rtos/rtos_riot_stackings.h +@@ -8,14 +8,9 @@ + #ifndef OPENOCD_RTOS_RTOS_RIOT_STACKINGS_H + #define OPENOCD_RTOS_RTOS_RIOT_STACKINGS_H + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- + #include "rtos.h" + + extern const struct rtos_register_stacking rtos_riot_cortex_m0_stacking; + extern const struct rtos_register_stacking rtos_riot_cortex_m34_stacking; + + #endif /* OPENOCD_RTOS_RTOS_RIOT_STACKINGS_H */ +- +diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c +index f83f0a1fb..5478080cf 100644 +--- a/src/rtos/rtos_standard_stackings.c ++++ b/src/rtos/rtos_standard_stackings.c +@@ -11,6 +11,7 @@ + + #include "rtos.h" + #include "target/armv7m.h" ++#include "rtos_standard_stackings.h" + + static const struct stack_register_offset rtos_standard_cortex_m3_stack_offsets[ARMV7M_NUM_CORE_REGS] = { + { ARMV7M_R0, 0x20, 32 }, /* r0 */ +diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h +index 2477fffd1..99fbe07e4 100644 +--- a/src/rtos/rtos_standard_stackings.h ++++ b/src/rtos/rtos_standard_stackings.h +@@ -8,10 +8,6 @@ + #ifndef OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H + #define OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- + #include "rtos.h" + + extern const struct rtos_register_stacking rtos_standard_cortex_m3_stacking; +diff --git a/src/rtos/rtos_ucos_iii_stackings.c b/src/rtos/rtos_ucos_iii_stackings.c +index 9ba5288bf..f1e248231 100644 +--- a/src/rtos/rtos_ucos_iii_stackings.c ++++ b/src/rtos/rtos_ucos_iii_stackings.c +@@ -9,11 +9,11 @@ + #include "config.h" + #endif + +-#include +-#include +-#include +-#include +-#include ++#include "rtos.h" ++#include "target/armv7m.h" ++#include "target/esirisc.h" ++#include "rtos_standard_stackings.h" ++#include "rtos_ucos_iii_stackings.h" + + static const struct stack_register_offset rtos_ucos_iii_cortex_m_stack_offsets[] = { + { ARMV7M_R0, 0x20, 32 }, /* r0 */ +diff --git a/src/rtos/rtos_ucos_iii_stackings.h b/src/rtos/rtos_ucos_iii_stackings.h +index 831c68e1c..dfe60b27b 100644 +--- a/src/rtos/rtos_ucos_iii_stackings.h ++++ b/src/rtos/rtos_ucos_iii_stackings.h +@@ -8,11 +8,7 @@ + #ifndef OPENOCD_RTOS_RTOS_UCOS_III_STACKINGS_H + #define OPENOCD_RTOS_RTOS_UCOS_III_STACKINGS_H + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif +- +-#include ++#include "rtos.h" + + extern const struct rtos_register_stacking rtos_ucos_iii_cortex_m_stacking; + extern const struct rtos_register_stacking rtos_ucos_iii_esi_risc_stacking; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0058-jtag-drivers-jlink-allow-SWD-multidrop.patch b/meta-oe/recipes-devtools/openocd/openocd/0058-jtag-drivers-jlink-allow-SWD-multidrop.patch new file mode 100644 index 000000000..ba75b3d35 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0058-jtag-drivers-jlink-allow-SWD-multidrop.patch @@ -0,0 +1,60 @@ +From 4423e05d9df8803e2311e70d5a2ffc55a92e5676 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Mon, 28 Nov 2022 10:54:48 +0100 +Subject: [PATCH] jtag/drivers/jlink: allow SWD multidrop + +SW-DPv2 and SWJ-DPv2 devices do not reply to DP_TARGETSEL write cmd. + +Ignore the received ACK after TARGETSEL write. + +While on it, use swd_ack_to_error_code() for unified error code +translation of the received ACK value for all other commands. + +Signed-off-by: Tomas Vanek +Change-Id: If978c88c8496e31581175385e59c32faebfd20aa +Reviewed-on: https://review.openocd.org/c/openocd/+/7383 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +Reviewed-by: zapb +--- + src/jtag/drivers/jlink.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c +index 0a96ac255..243d1a46b 100644 +--- a/src/jtag/drivers/jlink.c ++++ b/src/jtag/drivers/jlink.c +@@ -1976,6 +1976,8 @@ struct pending_scan_result { + void *buffer; + /** Offset in the destination buffer */ + unsigned buffer_offset; ++ /** SWD command */ ++ uint8_t swd_cmd; + }; + + #define MAX_PENDING_SCAN_RESULTS 256 +@@ -2179,12 +2181,13 @@ static int jlink_swd_run_queue(void) + } + + for (i = 0; i < pending_scan_results_length; i++) { ++ /* Devices do not reply to DP_TARGETSEL write cmd, ignore received ack */ ++ bool check_ack = swd_cmd_returns_ack(pending_scan_results_buffer[i].swd_cmd); + int ack = buf_get_u32(tdo_buffer, pending_scan_results_buffer[i].first, 3); +- +- if (ack != SWD_ACK_OK) { ++ if (check_ack && ack != SWD_ACK_OK) { + LOG_DEBUG("SWD ack not OK: %d %s", ack, + ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK"); +- queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL; ++ queued_retval = swd_ack_to_error_code(ack); + goto skip; + } else if (pending_scan_results_buffer[i].length) { + uint32_t data = buf_get_u32(tdo_buffer, 3 + pending_scan_results_buffer[i].first, 32); +@@ -2221,6 +2224,7 @@ static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint3 + if (queued_retval != ERROR_OK) + return; + ++ pending_scan_results_buffer[pending_scan_results_length].swd_cmd = cmd; + cmd |= SWD_CMD_START | SWD_CMD_PARK; + + jlink_queue_data_out(&cmd, 8); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0059-tcl-target-add-rescue-mode-to-RP2040-config.patch b/meta-oe/recipes-devtools/openocd/openocd/0059-tcl-target-add-rescue-mode-to-RP2040-config.patch new file mode 100644 index 000000000..3a4a96e00 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0059-tcl-target-add-rescue-mode-to-RP2040-config.patch @@ -0,0 +1,71 @@ +From 0b6f53e94cd81ee9c85ddc122004fa403b9cc454 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Sun, 2 Oct 2022 14:46:11 +0200 +Subject: [PATCH] tcl/target: add rescue mode to RP2040 config + +Integrate a rescue mode inspired by [1]. + +The current OpenOCD must be restarted before normal work with the RP2040 +because the rescue debug port must not be activated (or the target +is reset every 'dap init'). To continue without restarting OpenOCD +we would need to switch off the configured rescue dap. + +Change-Id: Ia05b960f06747063550c166e461939d92e232830 +Link: [1] https://github.com/raspberrypi/openocd/blob/rp2040/tcl/target/rp2040-rescue.cfg +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7327 +Reviewed-by: Jonathan Bell +Reviewed-by: Antonio Borneo +Tested-by: jenkins +--- + tcl/target/rp2040.cfg | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/tcl/target/rp2040.cfg b/tcl/target/rp2040.cfg +index 0593e03ba..de76b4e29 100644 +--- a/tcl/target/rp2040.cfg ++++ b/tcl/target/rp2040.cfg +@@ -26,6 +26,13 @@ if { [info exists CPUTAPID] } { + set _CPUTAPID 0x01002927 + } + ++# Set to '1' to start rescue mode ++if { [info exists RESCUE] } { ++ set _RESCUE $RESCUE ++} else { ++ set _RESCUE 0 ++} ++ + # Set to '0' or '1' for single core configuration, 'SMP' for -rtos hwthread + # handling of both cores, anything else for isolated debugging of both cores + if { [info exists USE_CORE] } { +@@ -37,6 +44,29 @@ set _BOTH_CORES [expr { $_USE_CORE != 0 && $_USE_CORE != 1 }] + + swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID + ++# The rescue debug port uses the DP CTRL/STAT bit DBGPWRUPREQ to reset the ++# PSM (power on state machine) of the RP2040 with a flag set in the ++# VREG_AND_POR_CHIP_RESET register. Once the reset is released ++# (by clearing the DBGPWRUPREQ flag), the bootrom will run, see this flag, ++# and halt. Allowing the user to load some fresh code, rather than loading ++# the potentially broken code stored in flash ++if { $_RESCUE } { ++ dap create $_CHIPNAME.rescue_dap -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id 0xf -ignore-syspwrupack ++ init ++ ++ # Clear DBGPWRUPREQ ++ $_CHIPNAME.rescue_dap dpreg 0x4 0x00000000 ++ ++ # Verifying CTRL/STAT is 0 ++ set _CTRLSTAT [$_CHIPNAME.rescue_dap dpreg 0x4] ++ if {[expr {$_CTRLSTAT & 0xf0000000}]} { ++ echo "Rescue failed, DP CTRL/STAT readback $_CTRLSTAT" ++ } else { ++ echo "Now restart OpenOCD without RESCUE flag and load code to RP2040" ++ } ++ shutdown ++} ++ + # core 0 + if { $_USE_CORE != 1 } { + dap create $_CHIPNAME.dap0 -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id 0 diff --git a/meta-oe/recipes-devtools/openocd/openocd/0060-flash-nor-spi-Add-some-zbit-flash-chips.patch b/meta-oe/recipes-devtools/openocd/openocd/0060-flash-nor-spi-Add-some-zbit-flash-chips.patch new file mode 100644 index 000000000..9b65c75fa --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0060-flash-nor-spi-Add-some-zbit-flash-chips.patch @@ -0,0 +1,50 @@ +From 9d97cace0e95437137e3c57e40347dfcce39ebc9 Mon Sep 17 00:00:00 2001 +From: Daniel Serpell +Date: Tue, 24 Jan 2023 23:54:43 -0300 +Subject: [PATCH] flash/nor/spi: Add some zbit flash chips. + +I have a RP2020 board from aliexpress that uses the ZB25VQ32 flash, this +allows openocd to correctly identify it with the full flash size. + +I also added other models, the datasheets can be found at: + +Link: https://datasheet.lcsc.com/lcsc/2203210916_Zbit-Semi-ZB25VQ16ASIG_C2982491.pdf +Link: https://datasheet.lcsc.com/lcsc/2003141132_Zbit-Semi-ZB25VQ32BSIG_C495744.pdf +Link: https://datasheet.lcsc.com/lcsc/2003141132_Zbit-Semi-ZB25VQ64ASIG_C495745.pdf +Link: https://datasheet.lcsc.com/lcsc/2006151421_Zbit-Semi-ZB25VQ128ASIG_C609616.pdf + +As noted by Andreas Bolsch, the devices supporting QSPI have different +ID in QPI mode than SPI, so two entries are needed in the table for each +one. + +Use 0x0B as qread command, as this does not need the dummy M7-0 +parameters. + +Signed-off-by: Daniel Serpell +Change-Id: Id99187b1963b02ac1a786b66bb352f5f48ed0ac2 +Reviewed-on: https://review.openocd.org/c/openocd/+/7445 +Reviewed-by: Andreas Bolsch +Reviewed-by: Antonio Borneo +Tested-by: jenkins +--- + src/flash/nor/spi.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c +index 373a9a144..9a606d545 100644 +--- a/src/flash/nor/spi.c ++++ b/src/flash/nor/spi.c +@@ -112,6 +112,13 @@ const struct flash_device flash_devices[] = { + FLASH_ID("gd gd25q128c", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001840c8, 0x100, 0x10000, 0x1000000), + FLASH_ID("gd gd25q256c", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x001940c8, 0x100, 0x10000, 0x2000000), + FLASH_ID("gd gd25q512mc", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x002040c8, 0x100, 0x10000, 0x4000000), ++ FLASH_ID("zbit zb25vq16", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0015605e, 0x100, 0x10000, 0x200000), ++ FLASH_ID("zbit zb25vq32", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016405e, 0x100, 0x10000, 0x400000), ++ FLASH_ID("zbit zb25vq32", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016605e, 0x100, 0x10000, 0x400000), /* QPI mode */ ++ FLASH_ID("zbit zb25vq64", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017405e, 0x100, 0x10000, 0x800000), ++ FLASH_ID("zbit zb25vq64", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017605e, 0x100, 0x10000, 0x800000), /* QPI mode */ ++ FLASH_ID("zbit zb25vq128", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018405e, 0x100, 0x10000, 0x1000000), ++ FLASH_ID("zbit zb25vq128", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018605e, 0x100, 0x10000, 0x1000000), /* QPI mode */ + FLASH_ID("issi is25lq040b", 0x03, 0xeb, 0x02, 0x20, 0xc7, 0x0013409d, 0x100, 0x1000, 0x80000), + FLASH_ID("issi is25lp032", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0016609d, 0x100, 0x10000, 0x400000), + FLASH_ID("issi is25lp064", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0017609d, 0x100, 0x10000, 0x800000), diff --git a/meta-oe/recipes-devtools/openocd/openocd/0061-target-arc-rewrite-command-arc-jtag-get-aux-reg-as-C.patch b/meta-oe/recipes-devtools/openocd/openocd/0061-target-arc-rewrite-command-arc-jtag-get-aux-reg-as-C.patch new file mode 100644 index 000000000..8d92ccec3 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0061-target-arc-rewrite-command-arc-jtag-get-aux-reg-as-C.patch @@ -0,0 +1,81 @@ +From 700cdbfac41014d9f3a9c12cbb13f01e59fb53d8 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 13:27:10 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc jtag get-aux-reg' as + COMMAND_HANDLER + +This also fixes an incorrect return ERROR_OK from a jim command. + +Change-Id: I3c51355e7e05965327ce819a3114e370f2de5249 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7407 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 35 ++++++++++++----------------------- + 1 file changed, 12 insertions(+), 23 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index 7a8004678..56eb0ec2d 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -318,39 +318,28 @@ static int jim_arc_set_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *ar + return ERROR_OK; + } + +-static int jim_arc_get_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(arc_handle_get_aux_reg) + { +- struct command_context *context; +- struct target *target; +- uint32_t regnum; +- uint32_t value; +- +- struct jim_getopt_info goi; +- JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); +- +- if (goi.argc != 1) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s ", Jim_GetString(argv[0], NULL)); +- return JIM_ERR; +- } +- +- context = current_command_context(interp); +- assert(context); ++ if (CMD_ARGC != 1) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- target = get_current_target(context); ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- return JIM_ERR; ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + + /* Register number */ +- JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); ++ uint32_t regnum; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], regnum); + + struct arc_common *arc = target_to_arc(target); + assert(arc); + ++ uint32_t value; + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, regnum, &value)); +- Jim_SetResultInt(interp, value); ++ ++ command_print(CMD, "0x%" PRIx32, value); + + return ERROR_OK; + } +@@ -445,7 +434,7 @@ static int jim_arc_set_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *a + static const struct command_registration arc_jtag_command_group[] = { + { + .name = "get-aux-reg", +- .jim_handler = jim_arc_get_aux_reg, ++ .handler = arc_handle_get_aux_reg, + .mode = COMMAND_EXEC, + .help = "Get AUX register by number. This command does a " + "raw JTAG request that bypasses OpenOCD register cache " diff --git a/meta-oe/recipes-devtools/openocd/openocd/0062-target-arc-rewrite-command-arc-jtag-set-aux-reg-as-C.patch b/meta-oe/recipes-devtools/openocd/openocd/0062-target-arc-rewrite-command-arc-jtag-set-aux-reg-as-C.patch new file mode 100644 index 000000000..c3aab0f52 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0062-target-arc-rewrite-command-arc-jtag-set-aux-reg-as-C.patch @@ -0,0 +1,78 @@ +From 551d85b123b38d34e15b4e978250ebdfe7b952f7 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 13:32:56 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc jtag set-aux-reg' as + COMMAND_HANDLER + +This also fixes an incorrect return ERROR_OK from a jim command. + +Change-Id: Iab9bc7c25181341a632f608a8ef2d8b0bea72520 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7408 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 35 +++++++++++------------------------ + 1 file changed, 11 insertions(+), 24 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index 56eb0ec2d..a6eb14f03 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -278,37 +278,24 @@ static struct jim_nvp nvp_add_reg_type_struct_opts[] = { + { .name = NULL, .value = -1 } + }; + +-static int jim_arc_set_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(arc_handle_set_aux_reg) + { ++ if (CMD_ARGC != 2) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- struct command_context *context; +- struct target *target; +- uint32_t regnum; +- uint32_t value; +- +- struct jim_getopt_info goi; +- JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); +- +- if (goi.argc != 2) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s ", Jim_GetString(argv[0], NULL)); +- return JIM_ERR; +- } +- +- context = current_command_context(interp); +- assert(context); +- +- target = get_current_target(context); ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- return JIM_ERR; ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + + /* Register number */ +- JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); ++ uint32_t regnum; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], regnum); + + /* Register value */ +- JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, &value)); ++ uint32_t value; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); + + struct arc_common *arc = target_to_arc(target); + assert(arc); +@@ -444,7 +431,7 @@ static const struct command_registration arc_jtag_command_group[] = { + }, + { + .name = "set-aux-reg", +- .jim_handler = jim_arc_set_aux_reg, ++ .handler = arc_handle_set_aux_reg, + .mode = COMMAND_EXEC, + .help = "Set AUX register by number. This command does a " + "raw JTAG request that bypasses OpenOCD register cache " diff --git a/meta-oe/recipes-devtools/openocd/openocd/0063-target-arc-rewrite-command-arc-jtag-get-core-reg-as-.patch b/meta-oe/recipes-devtools/openocd/openocd/0063-target-arc-rewrite-command-arc-jtag-get-core-reg-as-.patch new file mode 100644 index 000000000..0a5b3531d --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0063-target-arc-rewrite-command-arc-jtag-get-core-reg-as-.patch @@ -0,0 +1,89 @@ +From 16af56f6001782752d23567ca78823e2db9c5828 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 13:38:58 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc jtag get-core-reg' as + COMMAND_HANDLER + +This also fixes an incorrect return ERROR_OK from a jim command. + +Change-Id: I1f9cf5d1dfa38b8a06042b5f54209e6ee2fc4e0e +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7409 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 39 ++++++++++++++------------------------- + 1 file changed, 14 insertions(+), 25 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index a6eb14f03..cede9487b 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -331,45 +331,34 @@ COMMAND_HANDLER(arc_handle_get_aux_reg) + return ERROR_OK; + } + +-static int jim_arc_get_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(arc_handle_get_core_reg) + { +- struct command_context *context; +- struct target *target; +- uint32_t regnum; +- uint32_t value; +- +- struct jim_getopt_info goi; +- JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); +- +- if (goi.argc != 1) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s ", Jim_GetString(argv[0], NULL)); +- return JIM_ERR; +- } +- +- context = current_command_context(interp); +- assert(context); ++ if (CMD_ARGC != 1) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- target = get_current_target(context); ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- return JIM_ERR; ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + + /* Register number */ +- JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); ++ uint32_t regnum; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], regnum); + if (regnum > CORE_REG_MAX_NUMBER || regnum == ARC_R61 || regnum == ARC_R62) { +- Jim_SetResultFormatted(goi.interp, "Core register number %i " ++ command_print(CMD, "Core register number %i " + "is invalid. Must less then 64 and not 61 and 62.", regnum); +- return JIM_ERR; ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + + struct arc_common *arc = target_to_arc(target); + assert(arc); + + /* Read value */ ++ uint32_t value; + CHECK_RETVAL(arc_jtag_read_core_reg_one(&arc->jtag_info, regnum, &value)); +- Jim_SetResultInt(interp, value); ++ ++ command_print(CMD, "0x%" PRIx32, value); + + return ERROR_OK; + } +@@ -441,7 +430,7 @@ static const struct command_registration arc_jtag_command_group[] = { + }, + { + .name = "get-core-reg", +- .jim_handler = jim_arc_get_core_reg, ++ .handler = arc_handle_get_core_reg, + .mode = COMMAND_EXEC, + .help = "Get/Set core register by number. This command does a " + "raw JTAG request that bypasses OpenOCD register cache " diff --git a/meta-oe/recipes-devtools/openocd/openocd/0064-target-arc-rewrite-command-arc-jtag-set-core-reg-as-.patch b/meta-oe/recipes-devtools/openocd/openocd/0064-target-arc-rewrite-command-arc-jtag-set-core-reg-as-.patch new file mode 100644 index 000000000..87cb7ddea --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0064-target-arc-rewrite-command-arc-jtag-set-core-reg-as-.patch @@ -0,0 +1,84 @@ +From f0cb5b027238f6beb0bee80a9d385716923ae6eb Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 13:44:00 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc jtag set-core-reg' as + COMMAND_HANDLER + +This also fixes an incorrect return ERROR_OK from a jim command. + +Change-Id: I72a522645f62b99b313573c8bad6d4f674c5ae53 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7410 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 38 +++++++++++++------------------------- + 1 file changed, 13 insertions(+), 25 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index cede9487b..34ddc6903 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -363,41 +363,29 @@ COMMAND_HANDLER(arc_handle_get_core_reg) + return ERROR_OK; + } + +-static int jim_arc_set_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(arc_handle_set_core_reg) + { +- struct command_context *context; +- struct target *target; +- uint32_t regnum; +- uint32_t value; +- +- struct jim_getopt_info goi; +- JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); +- +- if (goi.argc != 2) { +- Jim_SetResultFormatted(goi.interp, +- "usage: %s ", Jim_GetString(argv[0], NULL)); +- return JIM_ERR; +- } +- +- context = current_command_context(interp); +- assert(context); ++ if (CMD_ARGC != 2) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- target = get_current_target(context); ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- return JIM_ERR; ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + + /* Register number */ +- JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); ++ uint32_t regnum; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], regnum); + if (regnum > CORE_REG_MAX_NUMBER || regnum == ARC_R61 || regnum == ARC_R62) { +- Jim_SetResultFormatted(goi.interp, "Core register number %i " ++ command_print(CMD, "Core register number %i " + "is invalid. Must less then 64 and not 61 and 62.", regnum); +- return JIM_ERR; ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + + /* Register value */ +- JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, &value)); ++ uint32_t value; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); + + struct arc_common *arc = target_to_arc(target); + assert(arc); +@@ -440,7 +428,7 @@ static const struct command_registration arc_jtag_command_group[] = { + }, + { + .name = "set-core-reg", +- .jim_handler = jim_arc_set_core_reg, ++ .handler = arc_handle_set_core_reg, + .mode = COMMAND_EXEC, + .help = "Get/Set core register by number. This command does a " + "raw JTAG request that bypasses OpenOCD register cache " diff --git a/meta-oe/recipes-devtools/openocd/openocd/0065-target-arc-rewrite-command-arc-get-reg-field-as-COMM.patch b/meta-oe/recipes-devtools/openocd/openocd/0065-target-arc-rewrite-command-arc-get-reg-field-as-COMM.patch new file mode 100644 index 000000000..31fc7f866 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0065-target-arc-rewrite-command-arc-get-reg-field-as-COMM.patch @@ -0,0 +1,116 @@ +From 996d6f383dfcffbc4550daedb622d3d006e8cd37 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 17:03:03 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc get-reg-field' as + COMMAND_HANDLER + +This also fixes several incorrect return ERROR_xxx from a jim +command. + +Change-Id: I34fe3552d3dc344eac67bf504c5d5709b707fdfd +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7411 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 51 ++++++++++++++------------------------------ + 1 file changed, 16 insertions(+), 35 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index 34ddc6903..264adc0b5 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -796,59 +796,40 @@ COMMAND_HANDLER(arc_set_reg_exists) + + /* arc reg-field ($reg_name) ($reg_field) + * Reads struct type register field */ +-static int jim_arc_get_reg_field(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(arc_handle_get_reg_field) + { +- struct jim_getopt_info goi; +- const char *reg_name, *field_name; +- uint32_t value; +- int retval; +- +- JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); +- +- LOG_DEBUG("Reading register field"); +- if (goi.argc != 2) { +- if (!goi.argc) +- Jim_WrongNumArgs(interp, goi.argc, goi.argv, " "); +- else if (goi.argc == 1) +- Jim_WrongNumArgs(interp, goi.argc, goi.argv, ""); +- else +- Jim_WrongNumArgs(interp, goi.argc, goi.argv, " "); ++ if (CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; +- } +- +- JIM_CHECK_RETVAL(jim_getopt_string(&goi, ®_name, NULL)); +- JIM_CHECK_RETVAL(jim_getopt_string(&goi, &field_name, NULL)); +- assert(reg_name); +- assert(field_name); + +- struct command_context * const ctx = current_command_context(interp); +- assert(ctx); +- struct target * const target = get_current_target(ctx); ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- return JIM_ERR; ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + +- retval = arc_reg_get_field(target, reg_name, field_name, &value); ++ const char *reg_name = CMD_ARGV[0]; ++ const char *field_name = CMD_ARGV[1]; ++ uint32_t value; ++ int retval = arc_reg_get_field(target, reg_name, field_name, &value); + + switch (retval) { + case ERROR_OK: + break; + case ERROR_ARC_REGISTER_NOT_FOUND: +- Jim_SetResultFormatted(goi.interp, ++ command_print(CMD, + "Register `%s' has not been found.", reg_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + case ERROR_ARC_REGISTER_IS_NOT_STRUCT: +- Jim_SetResultFormatted(goi.interp, ++ command_print(CMD, + "Register `%s' must have 'struct' type.", reg_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + case ERROR_ARC_REGISTER_FIELD_NOT_FOUND: +- Jim_SetResultFormatted(goi.interp, ++ command_print(CMD, + "Field `%s' has not been found in register `%s'.", + field_name, reg_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + case ERROR_ARC_FIELD_IS_NOT_BITFIELD: +- Jim_SetResultFormatted(goi.interp, ++ command_print(CMD, + "Field `%s' is not a 'bitfield' field in a structure.", + field_name); + return ERROR_COMMAND_ARGUMENT_INVALID; +@@ -857,9 +838,9 @@ static int jim_arc_get_reg_field(Jim_Interp *interp, int argc, Jim_Obj * const * + return retval; + } + +- Jim_SetResultInt(interp, value); ++ command_print(CMD, "0x%" PRIx32, value); + +- return JIM_OK; ++ return ERROR_OK; + } + + COMMAND_HANDLER(arc_l1_cache_disable_auto_cmd) +@@ -1002,7 +983,7 @@ static const struct command_registration arc_core_command_handlers[] = { + }, + { + .name = "get-reg-field", +- .jim_handler = jim_arc_get_reg_field, ++ .handler = arc_handle_get_reg_field, + .mode = COMMAND_ANY, + .usage = " ", + .help = "Returns value of field in a register with 'struct' type.", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0066-target-arc-rewrite-command-arc-num-actionpoints-as-C.patch b/meta-oe/recipes-devtools/openocd/openocd/0066-target-arc-rewrite-command-arc-num-actionpoints-as-C.patch new file mode 100644 index 000000000..a6cc0fd28 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0066-target-arc-rewrite-command-arc-num-actionpoints-as-C.patch @@ -0,0 +1,105 @@ +From da76ba610b8e6b05de3a837926d06f8e7d964b97 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 17:14:15 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc num-actionpoints' as + COMMAND_HANDLER + +Also drop arc_cmd_jim_get_uint32() that is now unused. + +Change-Id: Ic26c3f008376db3f01215bf736fca736dd1c1a4f +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7412 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 44 +++++++++++++------------------------------- + 1 file changed, 13 insertions(+), 31 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index 264adc0b5..e7c54446e 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -22,14 +22,6 @@ + * ------------------------------------------------------------------------- */ + + +-static int arc_cmd_jim_get_uint32(struct jim_getopt_info *goi, uint32_t *value) +-{ +- jim_wide value_wide; +- JIM_CHECK_RETVAL(jim_getopt_wide(goi, &value_wide)); +- *value = (uint32_t)value_wide; +- return JIM_OK; +-} +- + enum add_reg_types { + CFG_ADD_REG_TYPE_FLAG, + CFG_ADD_REG_TYPE_STRUCT, +@@ -863,27 +855,17 @@ COMMAND_HANDLER(arc_l2_cache_disable_auto_cmd) + &arc->has_l2cache, "target has l2 cache enabled"); + } + +-static int jim_handle_actionpoints_num(Jim_Interp *interp, int argc, +- Jim_Obj * const *argv) ++COMMAND_HANDLER(arc_handle_actionpoints_num) + { +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc - 1, argv + 1); +- + LOG_DEBUG("-"); + +- if (goi.argc >= 2) { +- Jim_WrongNumArgs(interp, goi.argc, goi.argv, "[]"); +- return JIM_ERR; +- } +- +- struct command_context *context = current_command_context(interp); +- assert(context); +- +- struct target *target = get_current_target(context); ++ if (CMD_ARGC >= 2) ++ return ERROR_COMMAND_SYNTAX_ERROR; + ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- return JIM_ERR; ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + + struct arc_common *arc = target_to_arc(target); +@@ -892,19 +874,19 @@ static int jim_handle_actionpoints_num(Jim_Interp *interp, int argc, + * "actionpoint reset, initiated by arc_set_actionpoints_num. */ + uint32_t ap_num = arc->actionpoints_num; + +- if (goi.argc == 1) { +- JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, &ap_num)); ++ if (CMD_ARGC == 1) { ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], ap_num); + int e = arc_set_actionpoints_num(target, ap_num); + if (e != ERROR_OK) { +- Jim_SetResultFormatted(goi.interp, ++ command_print(CMD, + "Failed to set number of actionpoints"); +- return JIM_ERR; ++ return e; + } + } + +- Jim_SetResultInt(interp, ap_num); ++ command_print(CMD, "%" PRIu32, ap_num); + +- return JIM_OK; ++ return ERROR_OK; + } + + /* ----- Exported target commands ------------------------------------------ */ +@@ -1004,7 +986,7 @@ static const struct command_registration arc_core_command_handlers[] = { + }, + { + .name = "num-actionpoints", +- .jim_handler = jim_handle_actionpoints_num, ++ .handler = arc_handle_actionpoints_num, + .mode = COMMAND_ANY, + .usage = "[]", + .help = "Prints or sets amount of actionpoints in the processor.", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0067-target-arc-fix-error-handling-in-command-arc-set-reg.patch b/meta-oe/recipes-devtools/openocd/openocd/0067-target-arc-fix-error-handling-in-command-arc-set-reg.patch new file mode 100644 index 000000000..7e8a5bcd0 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0067-target-arc-fix-error-handling-in-command-arc-set-reg.patch @@ -0,0 +1,40 @@ +From 18bafdce615132311fd34f2e1bdf57c193d14097 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 17:20:06 +0100 +Subject: [PATCH] target: arc: fix error handling in command 'arc + set-reg-exists' + +The command is specified through COMMAND_HANDLER. It should not +return JIM_OK / JIM_ERR. + +Change-Id: I56666414d49b0298ecc23ec7ef30c77e1e27afa8 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7413 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index e7c54446e..fb1817de6 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -763,7 +763,7 @@ COMMAND_HANDLER(arc_set_reg_exists) + struct target * const target = get_current_target(CMD_CTX); + if (!target) { + command_print(CMD, "Unable to get current target."); +- return JIM_ERR; ++ return ERROR_FAIL; + } + + if (!CMD_ARGC) { +@@ -783,7 +783,7 @@ COMMAND_HANDLER(arc_set_reg_exists) + r->exist = true; + } + +- return JIM_OK; ++ return ERROR_OK; + } + + /* arc reg-field ($reg_name) ($reg_field) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0068-helper-nvp-add-openocd-nvp-files.patch b/meta-oe/recipes-devtools/openocd/openocd/0068-helper-nvp-add-openocd-nvp-files.patch new file mode 100644 index 000000000..dbfb2fcb3 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0068-helper-nvp-add-openocd-nvp-files.patch @@ -0,0 +1,205 @@ +From ea6a99208e1bc41a878234f7220501e26ec4a7f1 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 26 Dec 2022 21:59:56 +0100 +Subject: [PATCH] helper: nvp: add openocd nvp files + +Long ago jim_nvp was part of jimtcl. When jimtcl dropped it, +OpenOCD kept copy of it in its code base. Current code of jim_nvp +is still related with jimtcl data types and functions. + +With the target of better isolating OpenOCD code from jimtcl, +create a new file nvp.c that re-proposes only the core of the old +jim_nvp, dropping any link with jimtcl and removing the string +'jim' either from the filename and from the code. +Keep the same license from the old code, as the new files are +clearly derived from it. + +Change-Id: I273448cf1f1484b10f6b6113ed7bb0fcf946482b +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7423 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/helper/Makefile.am | 4 ++- + src/helper/nvp.c | 67 +++++++++++++++++++++++++++++++++++++ + src/helper/nvp.h | 75 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 145 insertions(+), 1 deletion(-) + create mode 100644 src/helper/nvp.c + create mode 100644 src/helper/nvp.h + +diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am +index c4c60d96b..e9c05cfc5 100644 +--- a/src/helper/Makefile.am ++++ b/src/helper/Makefile.am +@@ -16,6 +16,7 @@ noinst_LTLIBRARIES += %D%/libhelper.la + %D%/util.c \ + %D%/jep106.c \ + %D%/jim-nvp.c \ ++ %D%/nvp.c \ + %D%/align.h \ + %D%/binarybuffer.h \ + %D%/bits.h \ +@@ -32,7 +33,8 @@ noinst_LTLIBRARIES += %D%/libhelper.la + %D%/system.h \ + %D%/jep106.h \ + %D%/jep106.inc \ +- %D%/jim-nvp.h ++ %D%/jim-nvp.h \ ++ %D%/nvp.h + + STARTUP_TCL_SRCS += %D%/startup.tcl + EXTRA_DIST += \ +diff --git a/src/helper/nvp.c b/src/helper/nvp.c +new file mode 100644 +index 000000000..7a8abc2e2 +--- /dev/null ++++ b/src/helper/nvp.c +@@ -0,0 +1,67 @@ ++// SPDX-License-Identifier: BSD-2-Clause-Views ++ ++/* ++ * Copyright 2005 Salvatore Sanfilippo ++ * Copyright 2005 Clemens Hintze ++ * Copyright 2005 patthoyts - Pat Thoyts ++ * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com ++ * Copyright 2008 Andrew Lunn ++ * Copyright 2008 Duane Ellis ++ * Copyright 2008 Uwe Klein ++ * Copyright 2008 Steve Bennett ++ * Copyright 2009 Nico Coesel ++ * Copyright 2009 Zachary T Welch zw@superlucidity.net ++ * Copyright 2009 David Brownell ++ * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved. ++ * ++ * This file is extracted from jim_nvp.c, originally part of jim TCL code. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++ ++#include ++#include ++ ++const struct nvp *nvp_name2value(const struct nvp *p, const char *name) ++{ ++ while (p->name) { ++ if (strcmp(name, p->name) == 0) ++ break; ++ p++; ++ } ++ return p; ++} ++ ++const struct nvp *nvp_value2name(const struct nvp *p, int value) ++{ ++ while (p->name) { ++ if (value == p->value) ++ break; ++ p++; ++ } ++ return p; ++} ++ ++void nvp_unknown_command_print(struct command_invocation *cmd, const struct nvp *nvp, ++ const char *param_name, const char *param_value) ++{ ++ if (param_name) ++ command_print_sameline(cmd, "%s: Unknown: %s, try one of: ", param_name, param_value); ++ else ++ command_print_sameline(cmd, "Unknown param: %s, try one of: ", param_value); ++ ++ while (nvp->name) { ++ if ((nvp + 1)->name) ++ command_print_sameline(cmd, "%s, ", nvp->name); ++ else ++ command_print(cmd, "or %s", nvp->name); ++ ++ nvp++; ++ } ++ ++ /* We assume nvp to be not empty and loop has been taken; no need to add a '\n' */ ++} +diff --git a/src/helper/nvp.h b/src/helper/nvp.h +new file mode 100644 +index 000000000..125164e4e +--- /dev/null ++++ b/src/helper/nvp.h +@@ -0,0 +1,75 @@ ++/* SPDX-License-Identifier: BSD-2-Clause-Views */ ++ ++/* ++ * Copyright 2005 Salvatore Sanfilippo ++ * Copyright 2005 Clemens Hintze ++ * Copyright 2005 patthoyts - Pat Thoyts ++ * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com ++ * Copyright 2008 Andrew Lunn ++ * Copyright 2008 Duane Ellis ++ * Copyright 2008 Uwe Klein ++ * Copyright 2008 Steve Bennett ++ * Copyright 2009 Nico Coesel ++ * Copyright 2009 Zachary T Welch zw@superlucidity.net ++ * Copyright 2009 David Brownell ++ * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved. ++ * ++ * This file is extracted from jim_nvp.h, originally part of jim TCL code. ++ */ ++ ++#ifndef OPENOCD_HELPER_NVP_H ++#define OPENOCD_HELPER_NVP_H ++ ++/** Name Value Pairs, aka: NVP ++ * - Given a string - return the associated int. ++ * - Given a number - return the associated string. ++ * . ++ * ++ * Very useful when the number is not a simple index into an array of ++ * known string, or there may be multiple strings (aliases) that mean then same ++ * thing. ++ * ++ * An NVP Table is terminated with ".name = NULL". ++ * ++ * During the 'name2value' operation, if no matching string is found ++ * the pointer to the terminal element (with p->name == NULL) is returned. ++ * ++ * Example: ++ * \code ++ * const struct nvp yn[] = { ++ * { "yes", 1 }, ++ * { "no" , 0 }, ++ * { "yep", 1 }, ++ * { "nope", 0 }, ++ * { NULL, -1 }, ++ * }; ++ * ++ * struct nvp *result; ++ * result = nvp_name2value(yn, "yes"); ++ * returns &yn[0]; ++ * result = nvp_name2value(yn, "no"); ++ * returns &yn[1]; ++ * result = jim_nvp_name2value(yn, "Blah"); ++ * returns &yn[4]; ++ * \endcode ++ * ++ * During the number2name operation, the first matching value is returned. ++ */ ++ ++struct nvp { ++ const char *name; ++ int value; ++}; ++ ++struct command_invocation; ++ ++/* Name Value Pairs Operations */ ++const struct nvp *nvp_name2value(const struct nvp *nvp_table, const char *name) ++ __attribute__((returns_nonnull, nonnull(1))); ++const struct nvp *nvp_value2name(const struct nvp *nvp_table, int v) ++ __attribute__((returns_nonnull, nonnull(1))); ++ ++void nvp_unknown_command_print(struct command_invocation *cmd, const struct nvp *nvp, ++ const char *param_name, const char *param_value); ++ ++#endif /* OPENOCD_HELPER_NVP_H */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0069-target-arc-rewrite-command-arc-add-reg-type-flags-as.patch b/meta-oe/recipes-devtools/openocd/openocd/0069-target-arc-rewrite-command-arc-add-reg-type-flags-as.patch new file mode 100644 index 000000000..18f8f6798 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0069-target-arc-rewrite-command-arc-add-reg-type-flags-as.patch @@ -0,0 +1,293 @@ +From 92ef27494c510a2df7cbbee8b19d5c0d4d943d40 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Tue, 27 Dec 2022 00:28:16 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc add-reg-type-flags' as + COMMAND_HANDLER + +Use a COMMAND_HELPER() to avoid memory leaks when the helper +COMMAND_PARSE_NUMBER() returns due to an error. + +While there: +- fix potential SIGSEGV due to dereference 'type' before checking + it's not NULL; +- fix an incorrect NUL byte termination while copying to + type->data_type.id and to bitfields[cur_field].name; +- fix some coding style error. + +Change-Id: Ide4cbc829871a6a523026ccc0d3100dadc2afd06 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7424 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 197 +++++++++++++++++++++---------------------- + 1 file changed, 94 insertions(+), 103 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index fb1817de6..32c62d0ca 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -13,6 +13,7 @@ + #endif + + #include "arc.h" ++#include + + /* -------------------------------------------------------------------------- + * +@@ -32,7 +33,7 @@ enum add_reg_type_flags { + CFG_ADD_REG_TYPE_FLAGS_FLAG, + }; + +-static struct jim_nvp nvp_add_reg_type_flags_opts[] = { ++static const struct nvp nvp_add_reg_type_flags_opts[] = { + { .name = "-name", .value = CFG_ADD_REG_TYPE_FLAGS_NAME }, + { .name = "-flag", .value = CFG_ADD_REG_TYPE_FLAGS_FLAG }, + { .name = NULL, .value = -1 } +@@ -114,53 +115,113 @@ static int jim_arc_read_reg_type_field(struct jim_getopt_info *goi, const char * + return e; + } + +-static int jim_arc_add_reg_type_flags(Jim_Interp *interp, int argc, +- Jim_Obj * const *argv) ++static COMMAND_HELPER(arc_handle_add_reg_type_flags_ops, struct arc_reg_data_type *type) + { +- struct jim_getopt_info goi; +- JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); ++ struct reg_data_type_flags_field *fields = type->reg_type_flags_field; ++ struct arc_reg_bitfield *bitfields = type->bitfields; ++ struct reg_data_type_flags *flags = &type->data_type_flags; ++ unsigned int cur_field = 0; + +- LOG_DEBUG("-"); ++ while (CMD_ARGC) { ++ const struct nvp *n = nvp_name2value(nvp_add_reg_type_flags_opts, CMD_ARGV[0]); ++ CMD_ARGC--; ++ CMD_ARGV++; ++ switch (n->value) { ++ case CFG_ADD_REG_TYPE_FLAGS_NAME: ++ if (!CMD_ARGC) ++ return ERROR_COMMAND_ARGUMENT_INVALID; + +- struct command_context *ctx; +- struct target *target; ++ const char *name = CMD_ARGV[0]; ++ CMD_ARGC--; ++ CMD_ARGV++; + +- ctx = current_command_context(interp); +- assert(ctx); +- target = get_current_target(ctx); +- if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- return JIM_ERR; ++ if (strlen(name) >= REG_TYPE_MAX_NAME_LENGTH) { ++ command_print(CMD, "Reg type name is too big."); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } ++ ++ strcpy((void *)type->data_type.id, name); ++ break; ++ ++ case CFG_ADD_REG_TYPE_FLAGS_FLAG: ++ if (CMD_ARGC < 2) ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ ++ uint32_t val; ++ const char *field_name = CMD_ARGV[0]; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], val); ++ CMD_ARGC -= 2; ++ CMD_ARGV += 2; ++ bitfields[cur_field].bitfield.start = val; ++ bitfields[cur_field].bitfield.end = val; ++ ++ if (strlen(field_name) >= REG_TYPE_MAX_NAME_LENGTH) { ++ command_print(CMD, "Reg type field_name is too big."); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } ++ ++ fields[cur_field].name = bitfields[cur_field].name; ++ strcpy(bitfields[cur_field].name, field_name); ++ ++ fields[cur_field].bitfield = &bitfields[cur_field].bitfield; ++ if (cur_field > 0) ++ fields[cur_field - 1].next = &fields[cur_field]; ++ else ++ flags->fields = fields; ++ ++ cur_field += 1; ++ break; ++ ++ default: ++ nvp_unknown_command_print(CMD, nvp_add_reg_type_flags_opts, NULL, CMD_ARGV[-1]); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } + } + +- int e = JIM_OK; ++ if (!type->data_type.id) { ++ command_print(CMD, "-name is a required option"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } + +- /* Check if the amount of arguments is not zero */ +- if (goi.argc <= 0) { +- Jim_SetResultFormatted(goi.interp, "The command has no arguments"); +- return JIM_ERR; ++ return ERROR_OK; ++} ++ ++COMMAND_HANDLER(arc_handle_add_reg_type_flags) ++{ ++ int retval; ++ ++ LOG_DEBUG("-"); ++ ++ struct target *target = get_current_target(CMD_CTX); ++ if (!target) { ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + ++ /* Check if the amount of arguments is not zero */ ++ if (CMD_ARGC == 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ + /* Estimate number of registers as (argc - 2)/3 as each -flag option has 2 + * arguments while -name is required. */ +- unsigned int fields_sz = (goi.argc - 2) / 3; +- unsigned int cur_field = 0; ++ unsigned int fields_sz = (CMD_ARGC - 2) / 3; + + /* The maximum amount of bitfields is 32 */ + if (fields_sz > 32) { +- Jim_SetResultFormatted(goi.interp, "The amount of bitfields exceed 32"); +- return JIM_ERR; ++ command_print(CMD, "The amount of bitfields exceed 32"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + + struct arc_reg_data_type *type = calloc(1, sizeof(*type)); +- struct reg_data_type_flags *flags = &type->data_type_flags; + struct reg_data_type_flags_field *fields = calloc(fields_sz, sizeof(*fields)); +- type->reg_type_flags_field = fields; + struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*bitfields)); +- if (!(type && fields && bitfields)) { +- Jim_SetResultFormatted(goi.interp, "Failed to allocate memory."); ++ if (!type || !fields || !bitfields) { ++ LOG_ERROR("Out of memory"); ++ retval = ERROR_FAIL; + goto fail; + } ++ struct reg_data_type_flags *flags = &type->data_type_flags; ++ type->reg_type_flags_field = fields; + + /* Initialize type */ + type->bitfields = bitfields; +@@ -170,92 +231,22 @@ static int jim_arc_add_reg_type_flags(Jim_Interp *interp, int argc, + type->data_type.reg_type_flags = flags; + flags->size = 4; /* For now ARC has only 32-bit registers */ + +- while (goi.argc > 0 && e == JIM_OK) { +- struct jim_nvp *n; +- e = jim_getopt_nvp(&goi, nvp_add_reg_type_flags_opts, &n); +- if (e != JIM_OK) { +- jim_getopt_nvp_unknown(&goi, nvp_add_reg_type_flags_opts, 0); +- continue; +- } +- +- switch (n->value) { +- case CFG_ADD_REG_TYPE_FLAGS_NAME: +- { +- const char *name = NULL; +- int name_len = 0; +- +- e = jim_arc_read_reg_name_field(&goi, &name, &name_len); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi.interp, "Unable to read reg name."); +- goto fail; +- } +- +- if (name_len > REG_TYPE_MAX_NAME_LENGTH) { +- Jim_SetResultFormatted(goi.interp, "Reg type name is too big."); +- goto fail; +- } +- +- strncpy((void *)type->data_type.id, name, name_len); +- if (!type->data_type.id) { +- Jim_SetResultFormatted(goi.interp, "Unable to setup reg type name."); +- goto fail; +- } +- +- break; +- } +- +- case CFG_ADD_REG_TYPE_FLAGS_FLAG: +- { +- const char *field_name = NULL; +- int field_name_len = 0; +- +- e = jim_arc_read_reg_type_field(&goi, &field_name, &field_name_len, bitfields, +- cur_field, CFG_ADD_REG_TYPE_FLAG); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi.interp, "Unable to add reg_type_flag field."); +- goto fail; +- } +- +- if (field_name_len > REG_TYPE_MAX_NAME_LENGTH) { +- Jim_SetResultFormatted(goi.interp, "Reg type field_name_len is too big."); +- goto fail; +- } +- +- fields[cur_field].name = bitfields[cur_field].name; +- strncpy(bitfields[cur_field].name, field_name, field_name_len); +- if (!fields[cur_field].name) { +- Jim_SetResultFormatted(goi.interp, "Unable to setup field name. "); +- goto fail; +- } +- +- fields[cur_field].bitfield = &(bitfields[cur_field].bitfield); +- if (cur_field > 0) +- fields[cur_field - 1].next = &(fields[cur_field]); +- else +- flags->fields = fields; +- +- cur_field += 1; +- break; +- } +- } +- } +- +- if (!type->data_type.id) { +- Jim_SetResultFormatted(goi.interp, "-name is a required option"); ++ retval = CALL_COMMAND_HANDLER(arc_handle_add_reg_type_flags_ops, type); ++ if (retval != ERROR_OK) + goto fail; +- } + + arc_reg_data_type_add(target, type); + + LOG_DEBUG("added flags type {name=%s}", type->data_type.id); + +- return JIM_OK; ++ return ERROR_OK; ++ + fail: + free(type); + free(fields); + free(bitfields); + +- return JIM_ERR; ++ return retval; + } + + /* Add struct register data type */ +@@ -924,7 +915,7 @@ static const struct command_registration arc_cache_group_handlers[] = { + static const struct command_registration arc_core_command_handlers[] = { + { + .name = "add-reg-type-flags", +- .jim_handler = jim_arc_add_reg_type_flags, ++ .handler = arc_handle_add_reg_type_flags, + .mode = COMMAND_CONFIG, + .usage = "-name -flag " + "[-flag ]...", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0070-target-arc-rewrite-command-arc-add-reg-type-struct-a.patch b/meta-oe/recipes-devtools/openocd/openocd/0070-target-arc-rewrite-command-arc-add-reg-type-struct-a.patch new file mode 100644 index 000000000..957567321 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0070-target-arc-rewrite-command-arc-add-reg-type-struct-a.patch @@ -0,0 +1,345 @@ +From 85f3b10a6914fd44c8f32d345654bed371d0667d Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Tue, 27 Dec 2022 00:56:55 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc add-reg-type-struct' as + COMMAND_HANDLER + +Use a COMMAND_HELPER() to avoid memory leaks when the helper +COMMAND_PARSE_NUMBER() returns due to an error. + +While there: +- fix potential SIGSEGV due to dereference 'type' before checking + it's not NULL; +- fix an incorrect NUL byte termination while copying to + type->data_type.id and to bitfields[cur_field].name; +- fix some coding style error; +- remove the now unused function jim_arc_read_reg_type_field(). + +Change-Id: I7158fd93b5d4742f11654b8ae4a7abd409ad06e2 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7425 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc_cmd.c | 252 +++++++++++++++++-------------------------- + 1 file changed, 101 insertions(+), 151 deletions(-) + +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index 32c62d0ca..3b0bf76f8 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -70,51 +70,6 @@ static int jim_arc_read_reg_name_field(struct jim_getopt_info *goi, + return e; + } + +-/* Helper function to read bitfields/flags of register type. */ +-static int jim_arc_read_reg_type_field(struct jim_getopt_info *goi, const char **field_name, int *field_name_len, +- struct arc_reg_bitfield *bitfields, int cur_field, int type) +-{ +- jim_wide start_pos, end_pos; +- +- int e = JIM_OK; +- if ((type == CFG_ADD_REG_TYPE_STRUCT && goi->argc < 3) || +- (type == CFG_ADD_REG_TYPE_FLAG && goi->argc < 2)) { +- Jim_SetResultFormatted(goi->interp, "Not enough arguments after -flag/-bitfield"); +- return JIM_ERR; +- } +- +- e = jim_getopt_string(goi, field_name, field_name_len); +- if (e != JIM_OK) +- return e; +- +- /* read start position of bitfield/flag */ +- e = jim_getopt_wide(goi, &start_pos); +- if (e != JIM_OK) +- return e; +- +- end_pos = start_pos; +- +- /* Check if any arguments remain, +- * set bitfields[cur_field].end if flag is multibit */ +- if (goi->argc > 0) +- /* Check current argv[0], if it is equal to "-flag", +- * than bitfields[cur_field].end remains start */ +- if ((strcmp(Jim_String(goi->argv[0]), "-flag") && type == CFG_ADD_REG_TYPE_FLAG) +- || (type == CFG_ADD_REG_TYPE_STRUCT)) { +- e = jim_getopt_wide(goi, &end_pos); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi->interp, "Error reading end position"); +- return e; +- } +- } +- +- bitfields[cur_field].bitfield.start = start_pos; +- bitfields[cur_field].bitfield.end = end_pos; +- if ((end_pos != start_pos) || (type == CFG_ADD_REG_TYPE_STRUCT)) +- bitfields[cur_field].bitfield.type = REG_TYPE_INT; +- return e; +-} +- + static COMMAND_HELPER(arc_handle_add_reg_type_flags_ops, struct arc_reg_data_type *type) + { + struct reg_data_type_flags_field *fields = type->reg_type_flags_field; +@@ -255,7 +210,7 @@ enum add_reg_type_struct { + CFG_ADD_REG_TYPE_STRUCT_BITFIELD, + }; + +-static struct jim_nvp nvp_add_reg_type_struct_opts[] = { ++static const struct nvp nvp_add_reg_type_struct_opts[] = { + { .name = "-name", .value = CFG_ADD_REG_TYPE_STRUCT_NAME }, + { .name = "-bitfield", .value = CFG_ADD_REG_TYPE_STRUCT_BITFIELD }, + { .name = NULL, .value = -1 } +@@ -424,53 +379,117 @@ static const struct command_registration arc_jtag_command_group[] = { + + + /* This function supports only bitfields. */ +-static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc, +- Jim_Obj * const *argv) ++static COMMAND_HELPER(arc_handle_add_reg_type_struct_opts, struct arc_reg_data_type *type) + { +- struct jim_getopt_info goi; +- JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); ++ struct reg_data_type_struct_field *fields = type->reg_type_struct_field; ++ struct arc_reg_bitfield *bitfields = type->bitfields; ++ struct reg_data_type_struct *struct_type = &type->data_type_struct; ++ unsigned int cur_field = 0; + +- LOG_DEBUG("-"); ++ while (CMD_ARGC) { ++ const struct nvp *n = nvp_name2value(nvp_add_reg_type_struct_opts, CMD_ARGV[0]); ++ CMD_ARGC--; ++ CMD_ARGV++; ++ switch (n->value) { ++ case CFG_ADD_REG_TYPE_STRUCT_NAME: ++ if (!CMD_ARGC) ++ return ERROR_COMMAND_ARGUMENT_INVALID; + +- struct command_context *ctx; +- struct target *target; ++ const char *name = CMD_ARGV[0]; ++ CMD_ARGC--; ++ CMD_ARGV++; + +- ctx = current_command_context(interp); +- assert(ctx); +- target = get_current_target(ctx); +- if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- return JIM_ERR; ++ if (strlen(name) >= REG_TYPE_MAX_NAME_LENGTH) { ++ command_print(CMD, "Reg type name is too big."); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } ++ ++ strcpy((void *)type->data_type.id, name); ++ break; ++ ++ case CFG_ADD_REG_TYPE_STRUCT_BITFIELD: ++ if (CMD_ARGC < 3) ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ ++ uint32_t start_pos, end_pos; ++ const char *field_name = CMD_ARGV[0]; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], start_pos); ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], end_pos); ++ CMD_ARGC -= 3; ++ CMD_ARGV += 3; ++ bitfields[cur_field].bitfield.start = start_pos; ++ bitfields[cur_field].bitfield.end = end_pos; ++ bitfields[cur_field].bitfield.type = REG_TYPE_INT; ++ ++ if (strlen(field_name) >= REG_TYPE_MAX_NAME_LENGTH) { ++ command_print(CMD, "Reg type field_name is too big."); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } ++ ++ fields[cur_field].name = bitfields[cur_field].name; ++ strcpy(bitfields[cur_field].name, field_name); ++ ++ fields[cur_field].bitfield = &bitfields[cur_field].bitfield; ++ fields[cur_field].use_bitfields = true; ++ if (cur_field > 0) ++ fields[cur_field - 1].next = &fields[cur_field]; ++ else ++ struct_type->fields = fields; ++ ++ cur_field += 1; ++ ++ break; ++ ++ default: ++ nvp_unknown_command_print(CMD, nvp_add_reg_type_struct_opts, NULL, CMD_ARGV[-1]); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } + } + +- int e = JIM_OK; ++ if (!type->data_type.id) { ++ command_print(CMD, "-name is a required option"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } + +- /* Check if the amount of arguments is not zero */ +- if (goi.argc <= 0) { +- Jim_SetResultFormatted(goi.interp, "The command has no arguments"); +- return JIM_ERR; ++ return ERROR_OK; ++} ++ ++COMMAND_HANDLER(arc_handle_add_reg_type_struct) ++{ ++ int retval; ++ ++ LOG_DEBUG("-"); ++ ++ struct target *target = get_current_target(CMD_CTX); ++ if (!target) { ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + ++ /* Check if the amount of arguments is not zero */ ++ if (CMD_ARGC == 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ + /* Estimate number of registers as (argc - 2)/4 as each -bitfield option has 3 + * arguments while -name is required. */ +- unsigned int fields_sz = (goi.argc - 2) / 4; +- unsigned int cur_field = 0; ++ unsigned int fields_sz = (CMD_ARGC - 2) / 4; + + /* The maximum amount of bitfields is 32 */ + if (fields_sz > 32) { +- Jim_SetResultFormatted(goi.interp, "The amount of bitfields exceed 32"); +- return JIM_ERR; ++ command_print(CMD, "The amount of bitfields exceed 32"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + + struct arc_reg_data_type *type = calloc(1, sizeof(*type)); +- struct reg_data_type_struct *struct_type = &type->data_type_struct; + struct reg_data_type_struct_field *fields = calloc(fields_sz, sizeof(*fields)); +- type->reg_type_struct_field = fields; + struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*bitfields)); +- if (!(type && fields && bitfields)) { +- Jim_SetResultFormatted(goi.interp, "Failed to allocate memory."); ++ if (!type || !fields || !bitfields) { ++ LOG_ERROR("Out of memory"); ++ retval = ERROR_FAIL; + goto fail; + } ++ struct reg_data_type_struct *struct_type = &type->data_type_struct; ++ type->reg_type_struct_field = fields; + + /* Initialize type */ + type->data_type.id = type->data_type_id; +@@ -480,91 +499,22 @@ static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc, + type->data_type.reg_type_struct = struct_type; + struct_type->size = 4; /* For now ARC has only 32-bit registers */ + +- while (goi.argc > 0 && e == JIM_OK) { +- struct jim_nvp *n; +- e = jim_getopt_nvp(&goi, nvp_add_reg_type_struct_opts, &n); +- if (e != JIM_OK) { +- jim_getopt_nvp_unknown(&goi, nvp_add_reg_type_struct_opts, 0); +- continue; +- } +- +- switch (n->value) { +- case CFG_ADD_REG_TYPE_STRUCT_NAME: +- { +- const char *name = NULL; +- int name_len = 0; +- +- e = jim_arc_read_reg_name_field(&goi, &name, &name_len); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi.interp, "Unable to read reg name."); +- goto fail; +- } +- +- if (name_len > REG_TYPE_MAX_NAME_LENGTH) { +- Jim_SetResultFormatted(goi.interp, "Reg type name is too big."); +- goto fail; +- } +- +- strncpy((void *)type->data_type.id, name, name_len); +- if (!type->data_type.id) { +- Jim_SetResultFormatted(goi.interp, "Unable to setup reg type name."); +- goto fail; +- } +- +- break; +- } +- case CFG_ADD_REG_TYPE_STRUCT_BITFIELD: +- { +- const char *field_name = NULL; +- int field_name_len = 0; +- e = jim_arc_read_reg_type_field(&goi, &field_name, &field_name_len, bitfields, +- cur_field, CFG_ADD_REG_TYPE_STRUCT); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi.interp, "Unable to add reg_type_struct field."); +- goto fail; +- } +- +- if (field_name_len > REG_TYPE_MAX_NAME_LENGTH) { +- Jim_SetResultFormatted(goi.interp, "Reg type field_name_len is too big."); +- goto fail; +- } +- +- fields[cur_field].name = bitfields[cur_field].name; +- strncpy(bitfields[cur_field].name, field_name, field_name_len); +- if (!fields[cur_field].name) { +- Jim_SetResultFormatted(goi.interp, "Unable to setup field name. "); +- goto fail; +- } +- +- fields[cur_field].bitfield = &(bitfields[cur_field].bitfield); +- fields[cur_field].use_bitfields = true; +- if (cur_field > 0) +- fields[cur_field - 1].next = &(fields[cur_field]); +- else +- struct_type->fields = fields; +- +- cur_field += 1; +- +- break; +- } +- } +- } +- +- if (!type->data_type.id) { +- Jim_SetResultFormatted(goi.interp, "-name is a required option"); ++ retval = CALL_COMMAND_HANDLER(arc_handle_add_reg_type_struct_opts, type); ++ if (retval != ERROR_OK) + goto fail; +- } + + arc_reg_data_type_add(target, type); ++ + LOG_DEBUG("added struct type {name=%s}", type->data_type.id); +- return JIM_OK; ++ ++ return ERROR_OK; + + fail: +- free(type); +- free(fields); +- free(bitfields); ++ free(type); ++ free(fields); ++ free(bitfields); + +- return JIM_ERR; ++ return retval; + } + + /* Add register */ +@@ -925,7 +875,7 @@ static const struct command_registration arc_core_command_handlers[] = { + }, + { + .name = "add-reg-type-struct", +- .jim_handler = jim_arc_add_reg_type_struct, ++ .handler = arc_handle_add_reg_type_struct, + .mode = COMMAND_CONFIG, + .usage = "-name -bitfield " + "[-bitfield ]...", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0071-target-arc-rewrite-command-arc-add-reg-as-COMMAND_HA.patch b/meta-oe/recipes-devtools/openocd/openocd/0071-target-arc-rewrite-command-arc-add-reg-as-COMMAND_HA.patch new file mode 100644 index 000000000..a78e69364 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0071-target-arc-rewrite-command-arc-add-reg-as-COMMAND_HA.patch @@ -0,0 +1,334 @@ +From 4a79372b6e6e511c9b7ad5cc97b85338ffb860e3 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Tue, 27 Dec 2022 02:38:25 +0100 +Subject: [PATCH] target: arc: rewrite command 'arc add-reg' as COMMAND_HANDLER + +While there, fix some coding style error and remove the now unused +function jim_arc_read_reg_name_field() and the macro +JIM_CHECK_RETVAL(). + +Change-Id: I140b4b929978b2936f2310e0b7d1735ba726c517 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7426 +Tested-by: jenkins +Reviewed-by: Evgeniy Didin +--- + src/target/arc.h | 10 -- + src/target/arc_cmd.c | 229 ++++++++++++++++++------------------------- + 2 files changed, 96 insertions(+), 143 deletions(-) + +diff --git a/src/target/arc.h b/src/target/arc.h +index bb70a598e..a351802ac 100644 +--- a/src/target/arc.h ++++ b/src/target/arc.h +@@ -253,16 +253,6 @@ struct arc_common { + } \ + } while (0) + +-#define JIM_CHECK_RETVAL(action) \ +- do { \ +- int __retval = (action); \ +- if (__retval != JIM_OK) { \ +- LOG_DEBUG("error while calling \"%s\"", \ +- # action); \ +- return __retval; \ +- } \ +- } while (0) +- + static inline struct arc_common *target_to_arc(struct target *target) + { + return target->arch_info; +diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c +index 3b0bf76f8..e7760b037 100644 +--- a/src/target/arc_cmd.c ++++ b/src/target/arc_cmd.c +@@ -55,21 +55,6 @@ static const char *validate_register(const struct arc_reg_desc * const reg, bool + return NULL; + } + +-/* Helper function to read the name of register type or register from +- * configure files */ +-static int jim_arc_read_reg_name_field(struct jim_getopt_info *goi, +- const char **name, int *name_len) +-{ +- int e = JIM_OK; +- +- if (!goi->argc) { +- Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-name ..."); +- return JIM_ERR; +- } +- e = jim_getopt_string(goi, name, name_len); +- return e; +-} +- + static COMMAND_HELPER(arc_handle_add_reg_type_flags_ops, struct arc_reg_data_type *type) + { + struct reg_data_type_flags_field *fields = type->reg_type_flags_field; +@@ -528,7 +513,7 @@ enum opts_add_reg { + CFG_ADD_REG_GENERAL, + }; + +-static struct jim_nvp opts_nvp_add_reg[] = { ++static const struct nvp opts_nvp_add_reg[] = { + { .name = "-name", .value = CFG_ADD_REG_NAME }, + { .name = "-num", .value = CFG_ADD_REG_ARCH_NUM }, + { .name = "-core", .value = CFG_ADD_REG_IS_CORE }, +@@ -546,155 +531,133 @@ void free_reg_desc(struct arc_reg_desc *r) + free(r); + } + +-static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++static COMMAND_HELPER(arc_handle_add_reg_do, struct arc_reg_desc *reg) + { +- struct jim_getopt_info goi; +- JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); +- +- struct arc_reg_desc *reg = calloc(1, sizeof(*reg)); +- if (!reg) { +- Jim_SetResultFormatted(goi.interp, "Failed to allocate memory."); +- return JIM_ERR; +- } +- + /* There is no architecture number that we could treat as invalid, so + * separate variable required to ensure that arch num has been set. */ + bool arch_num_set = false; + const char *type_name = "int"; /* Default type */ +- int type_name_len = strlen(type_name); +- int e = ERROR_OK; + + /* At least we need to specify 4 parameters: name, number and gdb_feature, + * which means there should be 6 arguments. Also there can be additional parameters + * "-type ", "-g" and "-core" or "-bcr" which makes maximum 10 parameters. */ +- if (goi.argc < 6 || goi.argc > 10) { +- free_reg_desc(reg); +- Jim_SetResultFormatted(goi.interp, +- "Should be at least 6 arguments and not greater than 10: " +- " -name -num -feature " +- " [-type ] [-core|-bcr] [-g]."); +- return JIM_ERR; +- } ++ if (CMD_ARGC < 6 || CMD_ARGC > 10) ++ return ERROR_COMMAND_SYNTAX_ERROR; + + /* Parse options. */ +- while (goi.argc > 0) { +- struct jim_nvp *n; +- e = jim_getopt_nvp(&goi, opts_nvp_add_reg, &n); +- if (e != JIM_OK) { +- jim_getopt_nvp_unknown(&goi, opts_nvp_add_reg, 0); +- free_reg_desc(reg); +- return e; +- } +- ++ while (CMD_ARGC) { ++ const struct nvp *n = nvp_name2value(opts_nvp_add_reg, CMD_ARGV[0]); ++ CMD_ARGC--; ++ CMD_ARGV++; + switch (n->value) { +- case CFG_ADD_REG_NAME: +- { +- const char *reg_name = NULL; +- int reg_name_len = 0; +- +- e = jim_arc_read_reg_name_field(&goi, ®_name, ®_name_len); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi.interp, "Unable to read register name."); +- free_reg_desc(reg); +- return e; +- } +- +- reg->name = strndup(reg_name, reg_name_len); +- break; +- } +- case CFG_ADD_REG_IS_CORE: +- reg->is_core = true; +- break; +- case CFG_ADD_REG_IS_BCR: +- reg->is_bcr = true; +- break; +- case CFG_ADD_REG_ARCH_NUM: +- { +- jim_wide archnum; +- +- if (!goi.argc) { +- free_reg_desc(reg); +- Jim_WrongNumArgs(interp, goi.argc, goi.argv, "-num ..."); +- return JIM_ERR; +- } +- +- e = jim_getopt_wide(&goi, &archnum); +- if (e != JIM_OK) { +- free_reg_desc(reg); +- return e; +- } +- +- reg->arch_num = archnum; +- arch_num_set = true; +- break; ++ case CFG_ADD_REG_NAME: ++ if (!CMD_ARGC) ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ ++ reg->name = strdup(CMD_ARGV[0]); ++ if (!reg->name) { ++ LOG_ERROR("Out of memory"); ++ return ERROR_FAIL; + } +- case CFG_ADD_REG_GDB_FEATURE: +- { +- const char *feature = NULL; +- int feature_len = 0; +- +- e = jim_arc_read_reg_name_field(&goi, &feature, &feature_len); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi.interp, "Unable to read gdb_feature."); +- free_reg_desc(reg); +- return e; +- } +- +- reg->gdb_xml_feature = strndup(feature, feature_len); +- break; ++ ++ CMD_ARGC--; ++ CMD_ARGV++; ++ break; ++ ++ case CFG_ADD_REG_IS_CORE: ++ reg->is_core = true; ++ break; ++ ++ case CFG_ADD_REG_IS_BCR: ++ reg->is_bcr = true; ++ break; ++ ++ case CFG_ADD_REG_ARCH_NUM: ++ if (!CMD_ARGC) ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg->arch_num); ++ CMD_ARGC--; ++ CMD_ARGV++; ++ ++ arch_num_set = true; ++ break; ++ ++ case CFG_ADD_REG_GDB_FEATURE: ++ if (!CMD_ARGC) ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ ++ reg->gdb_xml_feature = strdup(CMD_ARGV[0]); ++ if (!reg->gdb_xml_feature) { ++ LOG_ERROR("Out of memory"); ++ return ERROR_FAIL; + } +- case CFG_ADD_REG_TYPE: +- e = jim_arc_read_reg_name_field(&goi, &type_name, &type_name_len); +- if (e != JIM_OK) { +- Jim_SetResultFormatted(goi.interp, "Unable to read register type."); +- free_reg_desc(reg); +- return e; +- } +- +- break; +- case CFG_ADD_REG_GENERAL: +- reg->is_general = true; +- break; +- default: +- LOG_DEBUG("Error: Unknown parameter"); +- free_reg_desc(reg); +- return JIM_ERR; ++ ++ CMD_ARGC--; ++ CMD_ARGV++; ++ break; ++ ++ case CFG_ADD_REG_TYPE: ++ if (!CMD_ARGC) ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ ++ type_name = CMD_ARGV[0]; ++ CMD_ARGC--; ++ CMD_ARGV++; ++ break; ++ ++ case CFG_ADD_REG_GENERAL: ++ reg->is_general = true; ++ break; ++ ++ default: ++ nvp_unknown_command_print(CMD, opts_nvp_add_reg, NULL, CMD_ARGV[-1]); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + } + + /* Check that required fields are set */ + const char * const errmsg = validate_register(reg, arch_num_set); + if (errmsg) { +- Jim_SetResultFormatted(goi.interp, errmsg); +- free_reg_desc(reg); +- return JIM_ERR; ++ command_print(CMD, "%s", errmsg); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + + /* Add new register */ +- struct command_context *ctx; +- struct target *target; +- +- ctx = current_command_context(interp); +- assert(ctx); +- target = get_current_target(ctx); ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- Jim_SetResultFormatted(goi.interp, "No current target"); +- free_reg_desc(reg); +- return JIM_ERR; ++ command_print(CMD, "No current target"); ++ return ERROR_FAIL; + } + + reg->target = target; + +- e = arc_reg_add(target, reg, type_name, type_name_len); +- if (e == ERROR_ARC_REGTYPE_NOT_FOUND) { +- Jim_SetResultFormatted(goi.interp, ++ int retval = arc_reg_add(target, reg, type_name, strlen(type_name)); ++ if (retval == ERROR_ARC_REGTYPE_NOT_FOUND) { ++ command_print(CMD, + "Cannot find type `%s' for register `%s'.", + type_name, reg->name); ++ return retval; ++ } ++ ++ return ERROR_OK; ++} ++ ++COMMAND_HANDLER(arc_handle_add_reg) ++{ ++ struct arc_reg_desc *reg = calloc(1, sizeof(*reg)); ++ if (!reg) { ++ LOG_ERROR("Out of memory"); ++ return ERROR_FAIL; ++ } ++ ++ int retval = CALL_COMMAND_HANDLER(arc_handle_add_reg_do, reg); ++ if (retval != ERROR_OK) { + free_reg_desc(reg); +- return JIM_ERR; ++ return retval; + } + +- return e; ++ return ERROR_OK; + } + + /* arc set-reg-exists ($reg_name)+ +@@ -887,7 +850,7 @@ static const struct command_registration arc_core_command_handlers[] = { + }, + { + .name = "add-reg", +- .jim_handler = jim_arc_add_reg, ++ .handler = arc_handle_add_reg, + .mode = COMMAND_CONFIG, + .usage = "-name -num -feature [-gdbnum ] " + "[-core|-bcr] [-type ] [-g]", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0072-flash-nor-stm32l4x-Add-revision-Z-for-STM32L552-562-.patch b/meta-oe/recipes-devtools/openocd/openocd/0072-flash-nor-stm32l4x-Add-revision-Z-for-STM32L552-562-.patch new file mode 100644 index 000000000..48cba6844 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0072-flash-nor-stm32l4x-Add-revision-Z-for-STM32L552-562-.patch @@ -0,0 +1,28 @@ +From b6021e856a9259aac5dcba45bb3a5d8ae307886b Mon Sep 17 00:00:00 2001 +From: Marc Schink +Date: Mon, 30 Jan 2023 16:38:45 +0100 +Subject: [PATCH] flash/nor/stm32l4x: Add revision 'Z' for STM32L552/562 + devices + +Change-Id: Icc6058ef1f43e969a2a9baadfaf382ac820a7b76 +Signed-off-by: Marc Schink +Reviewed-on: https://review.openocd.org/c/openocd/+/7468 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/stm32l4x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c +index c67dbf75d..02e737b87 100644 +--- a/src/flash/nor/stm32l4x.c ++++ b/src/flash/nor/stm32l4x.c +@@ -318,7 +318,7 @@ static const struct stm32l4_rev stm32l4p_l4qxx_revs[] = { + }; + + static const struct stm32l4_rev stm32l55_l56xx_revs[] = { +- { 0x1000, "A" }, { 0x2000, "B" }, ++ { 0x1000, "A" }, { 0x2000, "B" }, { 0x2001, "Z" }, + }; + + static const struct stm32l4_rev stm32g49_g4axx_revs[] = { diff --git a/meta-oe/recipes-devtools/openocd/openocd/0073-README-Remove-statement-about-libjaylink-Git-submodu.patch b/meta-oe/recipes-devtools/openocd/openocd/0073-README-Remove-statement-about-libjaylink-Git-submodu.patch new file mode 100644 index 000000000..eeaefaf0e --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0073-README-Remove-statement-about-libjaylink-Git-submodu.patch @@ -0,0 +1,28 @@ +From 1998b1e5a89e57b2d1109bc36d6af916106103ff Mon Sep 17 00:00:00 2001 +From: Marc Schink +Date: Thu, 2 Feb 2023 14:25:27 +0100 +Subject: [PATCH] README: Remove statement about libjaylink Git submodule + +Change-Id: I552c08979849c66d7f8f559ccfd49d27f8b68bb8 +Signed-off-by: Marc Schink +Reviewed-on: https://review.openocd.org/c/openocd/+/7470 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + README | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/README b/README +index 2f71cfc6a..7d3f10def 100644 +--- a/README ++++ b/README +@@ -240,8 +240,7 @@ Optional CMSIS-DAP adapter driver needs HIDAPI library. + + Optional linuxgpiod adapter driver needs libgpiod library. + +-Optional JLink adapter driver needs libjaylink; build from git can +-retrieve libjaylink as git submodule. ++Optional J-Link adapter driver needs libjaylink library. + + Optional ARM disassembly needs capstone library. + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0074-new-SPI-memory-devices-continuation-code-for-manufac.patch b/meta-oe/recipes-devtools/openocd/openocd/0074-new-SPI-memory-devices-continuation-code-for-manufac.patch new file mode 100644 index 000000000..b54eeecc7 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0074-new-SPI-memory-devices-continuation-code-for-manufac.patch @@ -0,0 +1,156 @@ +From 85ae73de03ebcc723842b7978a6c94b73166f027 Mon Sep 17 00:00:00 2001 +From: Andreas Bolsch +Date: Wed, 9 Mar 2022 17:22:50 +0100 +Subject: [PATCH] new SPI memory devices, continuation code for manufacturer id + +A bunch of new SPI flash (Adesto, Cypress, XTX Tech, mainly octal) +IDs and SPI FRAM (Infineon) IDs added. Backward compatible change +of ID interpretation: The previously unused 4th byte now acts +as continuation code (0x7F) count for manufacturer id, cf. +JEDEC JEP106BC. Currently this affects only some recent octal flash +and FRAM devices, which are only supported by stmqspi and cmspi +flash drivers. + +Change-Id: Ibdcac81a84c636dc68439add4461b959df429bca +Signed-off-by: Andreas Bolsch +Reviewed-on: https://review.openocd.org/c/openocd/+/6929 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/flash/nor/spi.c | 73 +++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 64 insertions(+), 9 deletions(-) + +diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c +index 9a606d545..b83df9677 100644 +--- a/src/flash/nor/spi.c ++++ b/src/flash/nor/spi.c +@@ -23,7 +23,9 @@ + * from device datasheets and Linux SPI flash drivers. */ + const struct flash_device flash_devices[] = { + /* name, read_cmd, qread_cmd, pprog_cmd, erase_cmd, chip_erase_cmd, device_id, +- * pagesize, sectorsize, size_in_bytes */ ++ * pagesize, sectorsize, size_in_bytes ++ * note: device id is usually 3 bytes long, however the unused highest byte counts ++ * continuation codes for manufacturer id as per JEP106xx */ + FLASH_ID("st m25p05", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00102020, 0x80, 0x8000, 0x10000), + FLASH_ID("st m25p10", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00112020, 0x80, 0x8000, 0x20000), + FLASH_ID("st m25p20", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00122020, 0x100, 0x10000, 0x40000), +@@ -51,12 +53,28 @@ const struct flash_device flash_devices[] = { + FLASH_ID("cyp s25fl064l", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00176001, 0x100, 0x10000, 0x800000), + FLASH_ID("cyp s25fl128l", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00186001, 0x100, 0x10000, 0x1000000), + FLASH_ID("cyp s25fl256l", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x00196001, 0x100, 0x10000, 0x2000000), ++ FLASH_ID("cyp s28hl256t", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x00195a34, 0x100, 0x40000, 0x2000000), /* page! */ ++ FLASH_ID("cyp s28hs256t", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x00195b34, 0x100, 0x40000, 0x2000000), /* page! */ ++ FLASH_ID("cyp s28hl512t", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a5a34, 0x100, 0x40000, 0x4000000), /* page! */ ++ FLASH_ID("cyp s28hs512t", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a5b34, 0x100, 0x40000, 0x4000000), /* page! */ ++ FLASH_ID("cyp s28hl01gt", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001b5a34, 0x100, 0x40000, 0x8000000), /* page! */ ++ FLASH_ID("cyp s28hs01gt", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001b5b34, 0x100, 0x40000, 0x8000000), /* page! */ + FLASH_ID("atmel 25f512", 0x03, 0x00, 0x02, 0x52, 0xc7, 0x0065001f, 0x80, 0x8000, 0x10000), + FLASH_ID("atmel 25f1024", 0x03, 0x00, 0x02, 0x52, 0x62, 0x0060001f, 0x100, 0x8000, 0x20000), + FLASH_ID("atmel 25f2048", 0x03, 0x00, 0x02, 0x52, 0x62, 0x0063001f, 0x100, 0x10000, 0x40000), + FLASH_ID("atmel 25f4096", 0x03, 0x00, 0x02, 0x52, 0x62, 0x0064001f, 0x100, 0x10000, 0x80000), + FLASH_ID("atmel 25fs040", 0x03, 0x00, 0x02, 0xd7, 0xc7, 0x0004661f, 0x100, 0x10000, 0x80000), ++ FLASH_ID("adesto 25sf041b", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001841f, 0x100, 0x10000, 0x80000), + FLASH_ID("adesto 25df081a", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001451f, 0x100, 0x10000, 0x100000), ++ FLASH_ID("adesto 25sf081b", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001851f, 0x100, 0x10000, 0x100000), ++ FLASH_ID("adesto 25sf161b", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001861f, 0x100, 0x10000, 0x200000), ++ FLASH_ID("adesto 25df321b", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001471f, 0x100, 0x10000, 0x400000), ++ FLASH_ID("adesto 25sf321b", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001871f, 0x100, 0x10000, 0x400000), ++ FLASH_ID("adesto 25xf641b", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001881f, 0x100, 0x10000, 0x800000), /* sf/qf */ ++ FLASH_ID("adesto 25xf128a", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001891f, 0x100, 0x10000, 0x1000000), /* sf/qf */ ++ FLASH_ID("adesto xp032", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0700a743, 0x100, 0x10000, 0x400000), /* 4-byte */ ++ FLASH_ID("adesto xp064b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0001a81f, 0x100, 0x10000, 0x800000), /* 4-byte */ ++ FLASH_ID("adesto xp128", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0000a91f, 0x100, 0x10000, 0x1000000), /* 4-byte */ + FLASH_ID("mac 25l512", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001020c2, 0x010, 0x10000, 0x10000), + FLASH_ID("mac 25l1005", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001120c2, 0x010, 0x10000, 0x20000), + FLASH_ID("mac 25l2005", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001220c2, 0x010, 0x10000, 0x40000), +@@ -78,6 +96,9 @@ const struct flash_device flash_devices[] = { + FLASH_ID("mac 25r3235f", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001628c2, 0x100, 0x10000, 0x400000), + FLASH_ID("mac 25r6435f", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001728c2, 0x100, 0x10000, 0x800000), + FLASH_ID("mac 25u1635e", 0x03, 0xeb, 0x02, 0x20, 0xc7, 0x003525c2, 0x100, 0x1000, 0x100000), ++ FLASH_ID("mac 66l1g45g", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001b20c2, 0x100, 0x10000, 0x8000000), ++ FLASH_ID("mac 66um1g45g", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x003b80c2, 0x100, 0x10000, 0x8000000), ++ FLASH_ID("mac 66lm1g45g", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x003b85c2, 0x100, 0x10000, 0x8000000), + FLASH_ID("micron n25q032", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0016ba20, 0x100, 0x10000, 0x400000), + FLASH_ID("micron n25q064", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0017ba20, 0x100, 0x10000, 0x800000), + FLASH_ID("micron n25q128", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0018ba20, 0x100, 0x10000, 0x1000000), +@@ -102,6 +123,10 @@ const struct flash_device flash_devices[] = { + FLASH_ID("win w25q256fv/jv", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001940ef, 0x100, 0x10000, 0x2000000), + FLASH_ID("win w25q256fv", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001960ef, 0x100, 0x10000, 0x2000000), /* QPI mode */ + FLASH_ID("win w25q256jv", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001970ef, 0x100, 0x10000, 0x2000000), ++ FLASH_ID("win w25q512jv", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x002040ef, 0x100, 0x10000, 0x4000000), ++ FLASH_ID("win w25q01jv", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x002140ef, 0x100, 0x10000, 0x8000000), ++ FLASH_ID("win w25q01jv-dtr", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x002170ef, 0x100, 0x10000, 0x8000000), ++ FLASH_ID("win w25q02jv-dtr", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x002270ef, 0x100, 0x10000, 0x10000000), + FLASH_ID("gd gd25q512", 0x03, 0x00, 0x02, 0x20, 0xc7, 0x001040c8, 0x100, 0x1000, 0x10000), + FLASH_ID("gd gd25q10", 0x03, 0x00, 0x02, 0x20, 0xc7, 0x001140c8, 0x100, 0x1000, 0x20000), + FLASH_ID("gd gd25q20", 0x03, 0x00, 0x02, 0x20, 0xc7, 0x001240c8, 0x100, 0x1000, 0x40000), +@@ -109,9 +134,10 @@ const struct flash_device flash_devices[] = { + FLASH_ID("gd gd25q16c", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001540c8, 0x100, 0x10000, 0x200000), + FLASH_ID("gd gd25q32c", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001640c8, 0x100, 0x10000, 0x400000), + FLASH_ID("gd gd25q64c", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001740c8, 0x100, 0x10000, 0x800000), +- FLASH_ID("gd gd25q128c", 0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001840c8, 0x100, 0x10000, 0x1000000), ++ FLASH_ID("gd gd25q128c", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x001840c8, 0x100, 0x10000, 0x1000000), + FLASH_ID("gd gd25q256c", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x001940c8, 0x100, 0x10000, 0x2000000), + FLASH_ID("gd gd25q512mc", 0x13, 0x00, 0x12, 0xdc, 0xc7, 0x002040c8, 0x100, 0x10000, 0x4000000), ++ FLASH_ID("gd gd25lx256e", 0x13, 0x0c, 0x12, 0xdc, 0xc7, 0x001968c8, 0x100, 0x10000, 0x2000000), + FLASH_ID("zbit zb25vq16", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0015605e, 0x100, 0x10000, 0x200000), + FLASH_ID("zbit zb25vq32", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016405e, 0x100, 0x10000, 0x400000), + FLASH_ID("zbit zb25vq32", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016605e, 0x100, 0x10000, 0x400000), /* QPI mode */ +@@ -128,6 +154,18 @@ const struct flash_device flash_devices[] = { + FLASH_ID("issi is25wp256d", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0019709d, 0x100, 0x10000, 0x2000000), + FLASH_ID("issi is25lp512m", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a609d, 0x100, 0x10000, 0x4000000), + FLASH_ID("issi is25wp512m", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a709d, 0x100, 0x10000, 0x4000000), ++ FLASH_ID("xtx xt25f02e", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0012400b, 0x100, 0x10000, 0x40000), ++ FLASH_ID("xtx xt25f04d", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0013400b, 0x100, 0x10000, 0x80000), ++ FLASH_ID("xtx xt25f08b", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0014400b, 0x100, 0x10000, 0x100000), ++ FLASH_ID("xtx xt25f16b", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0015400b, 0x100, 0x10000, 0x200000), ++ FLASH_ID("xtx xt25f32b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016400b, 0x100, 0x10000, 0x200000), ++ FLASH_ID("xtx xt25f64b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017400b, 0x100, 0x10000, 0x400000), ++ FLASH_ID("xtx xt25f128b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018400b, 0x100, 0x10000, 0x800000), ++ FLASH_ID("xtx xt25q08d", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0014600b, 0x100, 0x10000, 0x100000), ++ FLASH_ID("xtx xt25q16b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0015600b, 0x100, 0x10000, 0x200000), ++ FLASH_ID("xtx xt25q32b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016600b, 0x100, 0x10000, 0x400000), /* exists ? */ ++ FLASH_ID("xtx xt25q64b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017600b, 0x100, 0x10000, 0x800000), ++ FLASH_ID("xtx xt25q128b", 0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018600b, 0x100, 0x10000, 0x1000000), + + /* FRAM, no erase commands, no write page or sectors */ + FRAM_ID("fu mb85rs16n", 0x03, 0, 0x02, 0x00010104, 0x800), +@@ -138,13 +176,30 @@ const struct flash_device flash_devices[] = { + FRAM_ID("fu mb85rs512t", 0x03, 0, 0x02, 0x00032604, 0x10000), + FRAM_ID("fu mb85rs1mt", 0x03, 0, 0x02, 0x00032704, 0x20000), + FRAM_ID("fu mb85rs2mta", 0x03, 0, 0x02, 0x00034804, 0x40000), +- FRAM_ID("cyp fm25v01a", 0x03, 0, 0x02, 0x000821c2, 0x4000), +- FRAM_ID("cyp fm25v02", 0x03, 0, 0x02, 0x000022c2, 0x8000), +- FRAM_ID("cyp fm25v02a", 0x03, 0, 0x02, 0x000822c2, 0x8000), +- FRAM_ID("cyp fm25v05", 0x03, 0, 0x02, 0x000023c2, 0x10000), +- FRAM_ID("cyp fm25v10", 0x03, 0, 0x02, 0x000024c2, 0x20000), +- FRAM_ID("cyp fm25v20a", 0x03, 0, 0x02, 0x000825c2, 0x40000), +- FRAM_ID("cyp fm25v40", 0x03, 0, 0x02, 0x004026c2, 0x80000), ++ FRAM_ID("cyp fm25v01a", 0x03, 0, 0x02, 0x060821c2, 0x4000), ++ FRAM_ID("cyp fm25v02", 0x03, 0, 0x02, 0x060022c2, 0x8000), ++ FRAM_ID("cyp fm25v02a", 0x03, 0, 0x02, 0x060822c2, 0x8000), ++ FRAM_ID("cyp fm25v05", 0x03, 0, 0x02, 0x060023c2, 0x10000), ++ FRAM_ID("cyp fm25v10", 0x03, 0, 0x02, 0x060024c2, 0x20000), ++ FRAM_ID("cyp fm25v20a", 0x03, 0, 0x02, 0x060825c2, 0x40000), ++ FRAM_ID("cyp fm25v40", 0x03, 0, 0x02, 0x064026c2, 0x80000), ++ FRAM_ID("cyp cy15b102qn", 0x03, 0, 0x02, 0x06002ac2, 0x40000), ++ FRAM_ID("cyp cy15v102qn", 0x03, 0, 0x02, 0x06042ac2, 0x40000), ++ FRAM_ID("cyp cy15b104qi", 0x03, 0, 0x02, 0x06012dc2, 0x80000), ++ FRAM_ID("cyp cy15b104qi", 0x03, 0, 0x02, 0x06a12dc2, 0x80000), ++ FRAM_ID("cyp cy15v104qi", 0x03, 0, 0x02, 0x06052dc2, 0x80000), ++ FRAM_ID("cyp cy15v104qi", 0x03, 0, 0x02, 0x06a52dc2, 0x80000), ++ FRAM_ID("cyp cy15b104qn", 0x03, 0, 0x02, 0x06402cc2, 0x80000), ++ FRAM_ID("cyp cy15b108qi", 0x03, 0, 0x02, 0x06012fc2, 0x100000), ++ FRAM_ID("cyp cy15b108qi", 0x03, 0, 0x02, 0x06a12fc2, 0x100000), ++ FRAM_ID("cyp cy15v108qi", 0x03, 0, 0x02, 0x06052fc2, 0x100000), ++ FRAM_ID("cyp cy15v108qi", 0x03, 0, 0x02, 0x06a52fc2, 0x100000), ++ FRAM_ID("cyp cy15b108qn", 0x03, 0, 0x02, 0x06012ec2, 0x100000), ++ FRAM_ID("cyp cy15b108qn", 0x03, 0, 0x02, 0x06032ec2, 0x100000), ++ FRAM_ID("cyp cy15b108qn", 0x03, 0, 0x02, 0x06a12ec2, 0x100000), ++ FRAM_ID("cyp cy15v108qn", 0x03, 0, 0x02, 0x06052ec2, 0x100000), ++ FRAM_ID("cyp cy15v108qn", 0x03, 0, 0x02, 0x06072ec2, 0x100000), ++ FRAM_ID("cyp cy15v108qn", 0x03, 0, 0x02, 0x06a52ec2, 0x100000), + + FLASH_ID(NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0) + }; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0075-flash-nor-spi-add-25pe-10-20-40-80-16.patch b/meta-oe/recipes-devtools/openocd/openocd/0075-flash-nor-spi-add-25pe-10-20-40-80-16.patch new file mode 100644 index 000000000..feae06481 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0075-flash-nor-spi-add-25pe-10-20-40-80-16.patch @@ -0,0 +1,31 @@ +From 79caea8745284ac1d2e8931335b58c679cd11882 Mon Sep 17 00:00:00 2001 +From: Daniel Anselmi +Date: Thu, 22 Dec 2022 22:28:21 +0100 +Subject: [PATCH] flash/nor/spi: add 25pe{10/20/40/80/16} + +Change-Id: Ic5660bff83b8636ef397482a3313971ecdff72c0 +Signed-off-by: Daniel Anselmi +Reviewed-on: https://review.openocd.org/c/openocd/+/7416 +Tested-by: jenkins +Reviewed-by: Andreas Bolsch +Reviewed-by: Antonio Borneo +--- + src/flash/nor/spi.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c +index b83df9677..3bcaa9f61 100644 +--- a/src/flash/nor/spi.c ++++ b/src/flash/nor/spi.c +@@ -26,6 +26,11 @@ const struct flash_device flash_devices[] = { + * pagesize, sectorsize, size_in_bytes + * note: device id is usually 3 bytes long, however the unused highest byte counts + * continuation codes for manufacturer id as per JEP106xx */ ++ FLASH_ID("st m25pe10", 0x03, 0x00, 0x02, 0xd8, 0x00, 0x00118020, 0x100, 0x10000, 0x20000), ++ FLASH_ID("st m25pe20", 0x03, 0x00, 0x02, 0xd8, 0x00, 0x00128020, 0x100, 0x10000, 0x40000), ++ FLASH_ID("st m25pe40", 0x03, 0x00, 0x02, 0xd8, 0x00, 0x00138020, 0x100, 0x10000, 0x80000), ++ FLASH_ID("st m25pe80", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00148020, 0x100, 0x10000, 0x100000), ++ FLASH_ID("st m25pe16", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00158020, 0x100, 0x10000, 0x200000), + FLASH_ID("st m25p05", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00102020, 0x80, 0x8000, 0x10000), + FLASH_ID("st m25p10", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00112020, 0x80, 0x8000, 0x20000), + FLASH_ID("st m25p20", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00122020, 0x100, 0x10000, 0x40000), diff --git a/meta-oe/recipes-devtools/openocd/openocd/0076-helper-command-drop-last-LF-n-from-sequence-of-comma.patch b/meta-oe/recipes-devtools/openocd/openocd/0076-helper-command-drop-last-LF-n-from-sequence-of-comma.patch new file mode 100644 index 000000000..a68f0c99f --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0076-helper-command-drop-last-LF-n-from-sequence-of-comma.patch @@ -0,0 +1,83 @@ +From c99c043f3f6e79e391debee29371360b0965b2d6 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 19:41:46 +0100 +Subject: [PATCH] helper: command: drop last LF ('\n') from sequence of + command_print() + +The OpenOCD commands produce their TCL text result through the +pair command_print() and command_print_sameline(). +The latter is used to concatenate output in a single line. + +At the end of a sequence of command_print(), the last LF is taken +as part of the command result, while it is not always needed, and +it is even annoying when the output of two commands needs to be +concatenate in a single line. + +Using command_print_sameline() in place of the last call to +command_print() would solve the problem but it's quite expensive +in term of coding to fix all the existing commands. + +Drop the last LF, if present. +Commands that would specifically need a LF as last char, can add +an extra LF at the end of the output. +Document this behavior in command.h. + +Change-Id: I6757c20fbfce923dd393083146e8d5a1f3b790b4 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7471 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/helper/command.c | 12 ++++++++++-- + src/helper/command.h | 11 +++++++++++ + 2 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/src/helper/command.c b/src/helper/command.c +index ca66cf7dd..12434ec90 100644 +--- a/src/helper/command.c ++++ b/src/helper/command.c +@@ -543,8 +543,16 @@ static int run_command(struct command_context *context, + if (retval != ERROR_OK) + LOG_DEBUG("Command '%s' failed with error code %d", + words[0], retval); +- /* Use the command output as the Tcl result */ +- Jim_SetResult(context->interp, cmd.output); ++ /* ++ * Use the command output as the Tcl result. ++ * Drop last '\n' to allow command output concatenation ++ * while keep using command_print() everywhere. ++ */ ++ const char *output_txt = Jim_String(cmd.output); ++ int len = strlen(output_txt); ++ if (len && output_txt[len - 1] == '\n') ++ --len; ++ Jim_SetResultString(context->interp, output_txt, len); + } + Jim_DecrRefCount(context->interp, cmd.output); + +diff --git a/src/helper/command.h b/src/helper/command.h +index 478e5c8ad..42cb9cb7d 100644 +--- a/src/helper/command.h ++++ b/src/helper/command.h +@@ -370,10 +370,21 @@ struct command_context *copy_command_context(struct command_context *cmd_ctx); + */ + void command_done(struct command_context *context); + ++/* ++ * command_print() and command_print_sameline() are used to produce the TCL ++ * output of OpenOCD commands. command_print() automatically adds a '\n' at ++ * the end or the format string. Use command_print_sameline() to avoid the ++ * trailing '\n', e.g. to concatenate the command output in the same line. ++ * The very last '\n' of the command is stripped away (see run_command()). ++ * For commands that strictly require a '\n' as last output character, add ++ * it explicitly with either an empty command_print() or with a '\n' in the ++ * last command_print() and add a comment to document it. ++ */ + void command_print(struct command_invocation *cmd, const char *format, ...) + __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); + void command_print_sameline(struct command_invocation *cmd, const char *format, ...) + __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); ++ + int command_run_line(struct command_context *context, char *line); + int command_run_linef(struct command_context *context, const char *format, ...) + __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0077-jtag-drivers-cmsis_dap-run-queue-on-reaching-transac.patch b/meta-oe/recipes-devtools/openocd/openocd/0077-jtag-drivers-cmsis_dap-run-queue-on-reaching-transac.patch new file mode 100644 index 000000000..7bae45d01 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0077-jtag-drivers-cmsis_dap-run-queue-on-reaching-transac.patch @@ -0,0 +1,47 @@ +From 0a20e78b759efa86a676b4a9fed4027fdd84e90c Mon Sep 17 00:00:00 2001 +From: Peter Collingbourne +Date: Fri, 17 Feb 2023 18:26:05 -0800 +Subject: [PATCH] jtag/drivers/cmsis_dap: run queue on reaching transaction + limit + +We currently fail the transfer when issuing more than 255 transactions +at once, e.g. + +> read_memory 0x10000000 32 256 +CMSIS-DAP transfer count mismatch: expected 257, got 1 + +This is because the protocol only supports 255 transactions per packet +(65535 for block transactions), and as a result we truncate the +transaction count when assembling the packet. Fix it by running the +queue when we hit the limit. + +Change-Id: Ia9e01e3af5ad035f2cf2a32292c9d66e57eafae9 +Signed-off-by: Peter Collingbourne +Fixes: 40bac8e8c4e5 ("jtag/drivers/cmsis_dap: improve USB packets filling") +Reviewed-on: https://review.openocd.org/c/openocd/+/7483 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/jtag/drivers/cmsis_dap.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c +index 0c42a7f1e..1e7a851e4 100644 +--- a/src/jtag/drivers/cmsis_dap.c ++++ b/src/jtag/drivers/cmsis_dap.c +@@ -1001,12 +1001,14 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) + block_cmd); + unsigned int resp_size = cmsis_dap_tfer_resp_size(write_count, read_count, + block_cmd); ++ unsigned int max_transfer_count = block_cmd ? 65535 : 255; + + /* Does the DAP Transfer command and the expected response fit into one packet? + * Run the queue also before a targetsel - it cannot be queued */ + if (cmd_size > tfer_max_command_size + || resp_size > tfer_max_response_size +- || targetsel_cmd) { ++ || targetsel_cmd ++ || write_count + read_count > max_transfer_count) { + if (cmsis_dap_handle->pending_fifo_block_count) + cmsis_dap_swd_read_process(cmsis_dap_handle, 0); + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0078-tlc-interface-does-fix-source-of-raspberrypi-gpio-co.patch b/meta-oe/recipes-devtools/openocd/openocd/0078-tlc-interface-does-fix-source-of-raspberrypi-gpio-co.patch new file mode 100644 index 000000000..a88e83fad --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0078-tlc-interface-does-fix-source-of-raspberrypi-gpio-co.patch @@ -0,0 +1,27 @@ +From fc30feb51a76e893646e2794c99a78dbdc0d251f Mon Sep 17 00:00:00 2001 +From: Tomas Deingruber +Date: Tue, 28 Feb 2023 23:17:56 +0000 +Subject: [PATCH] tlc/interface: does fix source of + raspberrypi-gpio-connector.cfg in raspberrypi-native.cfg + +Fixes: bec6c0eb094f (tcl/interface: universal config for all Raspberry Pi models) +Signed-off-by: Tomas Deingruber +Change-Id: I632c8acd84974937849b5fdf2943239def17bd6d +Reviewed-on: https://review.openocd.org/c/openocd/+/7512 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +Reviewed-by: Antonio Borneo +--- + tcl/interface/raspberrypi-native.cfg | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tcl/interface/raspberrypi-native.cfg b/tcl/interface/raspberrypi-native.cfg +index 95426c226..7224723d6 100644 +--- a/tcl/interface/raspberrypi-native.cfg ++++ b/tcl/interface/raspberrypi-native.cfg +@@ -68,4 +68,4 @@ set speed_coeff [expr { $clock / $clocks_per_timing_loop }] + # The coefficients depend on system clock and CPU frequency scaling. + bcm2835gpio speed_coeffs $speed_coeff $speed_offset + +-source raspberrypi-gpio-connector.cfg ++source [find interface/raspberrypi-gpio-connector.cfg] diff --git a/meta-oe/recipes-devtools/openocd/openocd/0079-tcl-board-at91sam9g20-ek-remove-outdated-FIXME.patch b/meta-oe/recipes-devtools/openocd/openocd/0079-tcl-board-at91sam9g20-ek-remove-outdated-FIXME.patch new file mode 100644 index 000000000..4b030aa95 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0079-tcl-board-at91sam9g20-ek-remove-outdated-FIXME.patch @@ -0,0 +1,31 @@ +From e1b0d5759a1e9221d534400505c6eb7e43abd051 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Fri, 3 Mar 2023 16:50:38 +0100 +Subject: [PATCH] tcl/board/at91sam9g20-ek: remove outdated FIXME + +It was fixed by e94180571 ("at91sam9: factorise cpu support") in 2011. + +Signed-off-by: Wolfram Sang +Change-Id: I95ea149b45a9902424bf9068b4a2830c17ddc6be +Reviewed-on: https://review.openocd.org/c/openocd/+/7525 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + tcl/board/at91sam9g20-ek.cfg | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg +index a5831cd91..4740471c8 100644 +--- a/tcl/board/at91sam9g20-ek.cfg ++++ b/tcl/board/at91sam9g20-ek.cfg +@@ -7,10 +7,6 @@ + # # + ################################################################################################# + +-# FIXME use some standard target config, maybe create one from this +-# +-# source [find target/...cfg] +- + source [find target/at91sam9g20.cfg] + + set _FLASHTYPE nandflash_cs3 diff --git a/meta-oe/recipes-devtools/openocd/openocd/0080-TODO-remove-outdated-AT91SAM92xx-entry.patch b/meta-oe/recipes-devtools/openocd/openocd/0080-TODO-remove-outdated-AT91SAM92xx-entry.patch new file mode 100644 index 000000000..b2a674c52 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0080-TODO-remove-outdated-AT91SAM92xx-entry.patch @@ -0,0 +1,31 @@ +From c8f56b4f00a1b8d7cc74f08b34466b2017c1f1dc Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Fri, 3 Mar 2023 17:00:19 +0100 +Subject: [PATCH] TODO: remove outdated AT91SAM92xx entry + +SAM9260 gained good generic infrastructure since 2009. And we always +want "improvements", no need for a TODO item. + +Signed-off-by: Wolfram Sang +Change-Id: I92551ef9d42ee47ad7441f2354587bbb45edc97e +Reviewed-on: https://review.openocd.org/c/openocd/+/7526 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +Reviewed-by: Antonio Borneo +--- + TODO | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/TODO b/TODO +index ebb6c9980..e4dded0ce 100644 +--- a/TODO ++++ b/TODO +@@ -202,8 +202,6 @@ https://lists.berlios.de/pipermail/openocd-development/2009-October/011506.html + - MC1322x support (JW/DE?) + - integrate and test support from JW (and DE?) + - get working with a known good interface (i.e. not today's jlink) +-- AT91SAM92xx: +- - improvements for unknown-board-atmel-at91sam9260.cfg (RD) + - STR9x: (ZW) + - improvements to str912.cfg to be more general purpose + - AVR: (SQ) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0081-drivers-libusb_helper-allow-external-use-of-jtag_lib.patch b/meta-oe/recipes-devtools/openocd/openocd/0081-drivers-libusb_helper-allow-external-use-of-jtag_lib.patch new file mode 100644 index 000000000..16d9a9794 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0081-drivers-libusb_helper-allow-external-use-of-jtag_lib.patch @@ -0,0 +1,45 @@ +From c7e0040689db1fc2673c117e038ffb3a88f6562b Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Mon, 6 Mar 2023 15:31:08 +0100 +Subject: [PATCH] drivers/libusb_helper: allow external use of + jtag_libusb_match_ids() + +Can be employed by a driver with custom libusb open. + +Change-Id: I00c8a01df8780891a8b7c30e2e34ab191acdf9a8 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7528 +Tested-by: jenkins +Reviewed-by: Wolfram Sang +Reviewed-by: Antonio Borneo +--- + src/jtag/drivers/libusb_helper.c | 2 +- + src/jtag/drivers/libusb_helper.h | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c +index 53dfd502d..4b098b482 100644 +--- a/src/jtag/drivers/libusb_helper.c ++++ b/src/jtag/drivers/libusb_helper.c +@@ -50,7 +50,7 @@ static int jtag_libusb_error(int err) + } + } + +-static bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc, ++bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc, + const uint16_t vids[], const uint16_t pids[]) + { + for (unsigned i = 0; vids[i]; i++) { +diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h +index 172c34598..799e3e6a9 100644 +--- a/src/jtag/drivers/libusb_helper.h ++++ b/src/jtag/drivers/libusb_helper.h +@@ -30,6 +30,8 @@ + typedef char * (*adapter_get_alternate_serial_fn)(struct libusb_device_handle *device, + struct libusb_device_descriptor *dev_desc); + ++bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc, ++ const uint16_t vids[], const uint16_t pids[]); + int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], + struct libusb_device_handle **out, + adapter_get_alternate_serial_fn adapter_get_alternate_serial); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0082-drivers-ftdi-prevent-misleading-error-msg-when-more-.patch b/meta-oe/recipes-devtools/openocd/openocd/0082-drivers-ftdi-prevent-misleading-error-msg-when-more-.patch new file mode 100644 index 000000000..ef88dc83a --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0082-drivers-ftdi-prevent-misleading-error-msg-when-more-.patch @@ -0,0 +1,111 @@ +From a8bc4e75b3dda3d32345fa310a3be724235d8fa8 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Mon, 6 Mar 2023 15:37:43 +0100 +Subject: [PATCH] drivers/ftdi: prevent misleading error msg when more vid/pids + configured + +The driver tries to open mpsse engine for each vid pid +pair in sequence. If more vid/pid pairs are configured and +the USB device does not correspond to the first pair, +the driver shows 'unable to open ftdi device ...' error. + +Match vid pid with the whole list as used in jtag_libusb_open() +instead of multiple mpsse_open() in for loop over vid/pid pairs. + +Change-Id: I8ef55205be221c727607fe25b81ae21de0d96f02 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7529 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +Reviewed-by: Wolfram Sang +--- + src/jtag/drivers/ftdi.c | 7 +------ + src/jtag/drivers/mpsse.c | 20 +++++++------------- + 2 files changed, 8 insertions(+), 19 deletions(-) + +diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c +index 3097d4129..6356a4929 100644 +--- a/src/jtag/drivers/ftdi.c ++++ b/src/jtag/drivers/ftdi.c +@@ -658,13 +658,8 @@ static int ftdi_initialize(void) + return ERROR_JTAG_INIT_FAILED; + } + +- for (int i = 0; ftdi_vid[i] || ftdi_pid[i]; i++) { +- mpsse_ctx = mpsse_open(&ftdi_vid[i], &ftdi_pid[i], ftdi_device_desc, ++ mpsse_ctx = mpsse_open(ftdi_vid, ftdi_pid, ftdi_device_desc, + adapter_get_required_serial(), adapter_usb_get_location(), ftdi_channel); +- if (mpsse_ctx) +- break; +- } +- + if (!mpsse_ctx) + return ERROR_JTAG_INIT_FAILED; + +diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c +index 18aeb38a4..9f2fdde9f 100644 +--- a/src/jtag/drivers/mpsse.c ++++ b/src/jtag/drivers/mpsse.c +@@ -13,6 +13,7 @@ + #include "helper/log.h" + #include "helper/replacements.h" + #include "helper/time_support.h" ++#include "libusb_helper.h" + #include + + /* Compatibility define for older libusb-1.0 */ +@@ -148,7 +149,7 @@ static bool device_location_equal(struct libusb_device *device, const char *loca + * Set any field to 0 as a wildcard. If the device is found true is returned, with ctx containing + * the already opened handle. ctx->interface must be set to the desired interface (channel) number + * prior to calling this function. */ +-static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, const uint16_t *pid, ++static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t vids[], const uint16_t pids[], + const char *product, const char *serial, const char *location) + { + struct libusb_device **list; +@@ -169,9 +170,7 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con + continue; + } + +- if (vid && *vid != desc.idVendor) +- continue; +- if (pid && *pid != desc.idProduct) ++ if (!jtag_libusb_match_ids(&desc, vids, pids)) + continue; + + err = libusb_open(device, &ctx->usb_dev); +@@ -203,7 +202,7 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con + libusb_free_device_list(list, 1); + + if (!found) { +- LOG_ERROR("no device found"); ++ /* The caller reports detailed error desc */ + return false; + } + +@@ -307,7 +306,7 @@ error: + return false; + } + +-struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const char *description, ++struct mpsse_ctx *mpsse_open(const uint16_t vids[], const uint16_t pids[], const char *description, + const char *serial, const char *location, int channel) + { + struct mpsse_ctx *ctx = calloc(1, sizeof(*ctx)); +@@ -343,14 +342,9 @@ struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const cha + goto error; + } + +- if (!open_matching_device(ctx, vid, pid, description, serial, location)) { +- /* Four hex digits plus terminating zero each */ +- char vidstr[5]; +- char pidstr[5]; +- LOG_ERROR("unable to open ftdi device with vid %s, pid %s, description '%s', " ++ if (!open_matching_device(ctx, vids, pids, description, serial, location)) { ++ LOG_ERROR("unable to open ftdi device with description '%s', " + "serial '%s' at bus location '%s'", +- vid ? sprintf(vidstr, "%04x", *vid), vidstr : "*", +- pid ? sprintf(pidstr, "%04x", *pid), pidstr : "*", + description ? description : "*", + serial ? serial : "*", + location ? location : "*"); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0083-flash-nor-at91samd-fix-RAM-size-for-SAMR34-35.patch b/meta-oe/recipes-devtools/openocd/openocd/0083-flash-nor-at91samd-fix-RAM-size-for-SAMR34-35.patch new file mode 100644 index 000000000..c3c424f87 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0083-flash-nor-at91samd-fix-RAM-size-for-SAMR34-35.patch @@ -0,0 +1,31 @@ +From 70d771c7b7d488c76452191fb1a2a8bdfa9a2f25 Mon Sep 17 00:00:00 2001 +From: Andrew Lalaev +Date: Sun, 5 Mar 2023 20:36:32 +0100 +Subject: [PATCH] flash/nor/at91samd: fix RAM size for SAMR34/35 + +According to the datasheets these MCUs have 40Kb RAM. + +Signed-off-by: Andrew Lalaev +Change-Id: I52b8a0c86035bccd6f3c1a478bb2e558bca4ae86 +Reviewed-on: https://review.openocd.org/c/openocd/+/7520 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/flash/nor/at91samd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c +index 33e86c76e..b3252e870 100644 +--- a/src/flash/nor/at91samd.c ++++ b/src/flash/nor/at91samd.c +@@ -243,8 +243,8 @@ static const struct samd_part saml21_parts[] = { + { 0x1F, "SAMR30E18A", 256, 32 }, + + /* SAMR34/R35 parts have integrated SAML21 with a lora radio */ +- { 0x28, "SAMR34J18", 256, 32 }, +- { 0x2B, "SAMR35J18", 256, 32 }, ++ { 0x28, "SAMR34J18", 256, 40 }, ++ { 0x2B, "SAMR35J18", 256, 40 }, + }; + + /* Known SAML22 parts. */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0084-flash-nor-at91samd-add-missing-SAMR34-35-part-number.patch b/meta-oe/recipes-devtools/openocd/openocd/0084-flash-nor-at91samd-add-missing-SAMR34-35-part-number.patch new file mode 100644 index 000000000..0248894e5 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0084-flash-nor-at91samd-add-missing-SAMR34-35-part-number.patch @@ -0,0 +1,32 @@ +From 8d1261c248796d5eee9ec8e646d16d653be984a6 Mon Sep 17 00:00:00 2001 +From: Andrew Lalaev +Date: Sun, 5 Mar 2023 20:41:14 +0100 +Subject: [PATCH] flash/nor/at91samd: add missing SAMR34/35 part numbers + +All DIDs are taken from "SAM R34/R35 Errata Sheet" (DS80000834A). + +Signed-off-by: Andrew Lalaev +Change-Id: Ie35f58e61bb02919c0676c91938c90192481d995 +Reviewed-on: https://review.openocd.org/c/openocd/+/7521 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/flash/nor/at91samd.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c +index b3252e870..416f07778 100644 +--- a/src/flash/nor/at91samd.c ++++ b/src/flash/nor/at91samd.c +@@ -244,7 +244,11 @@ static const struct samd_part saml21_parts[] = { + + /* SAMR34/R35 parts have integrated SAML21 with a lora radio */ + { 0x28, "SAMR34J18", 256, 40 }, ++ { 0x29, "SAMR34J17", 128, 24 }, ++ { 0x2A, "SAMR34J16", 64, 12 }, + { 0x2B, "SAMR35J18", 256, 40 }, ++ { 0x2C, "SAMR35J17", 128, 24 }, ++ { 0x2D, "SAMR35J16", 64, 12 }, + }; + + /* Known SAML22 parts. */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0085-doc-add-missing-FreeRTOS-symbol.patch b/meta-oe/recipes-devtools/openocd/openocd/0085-doc-add-missing-FreeRTOS-symbol.patch new file mode 100644 index 000000000..964c8746d --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0085-doc-add-missing-FreeRTOS-symbol.patch @@ -0,0 +1,31 @@ +From a7f8a1d7fb8e6628f34340a5777ce600dc27f8d8 Mon Sep 17 00:00:00 2001 +From: Chao Du +Date: Wed, 8 Mar 2023 07:17:13 +0000 +Subject: [PATCH] doc: add missing FreeRTOS symbol + +A new FreeRTOS symbol xSchedulerRunning was added into the symbol list. +But the doc was not updated accordingly. + +Signed-off-by: Chao Du +Change-Id: If1b18591e2681477ad96f1dea566cc2547097767 +Reviewed-on: https://review.openocd.org/c/openocd/+/7531 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +Reviewed-by: Antonio Borneo +--- + doc/openocd.texi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index 6c853f2ce..414b4c405 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -11887,7 +11887,7 @@ _tx_thread_current_ptr, _tx_thread_created_ptr, _tx_thread_created_count. + @raggedright + pxCurrentTCB, pxReadyTasksLists, xDelayedTaskList1, xDelayedTaskList2, + pxDelayedTaskList, pxOverflowDelayedTaskList, xPendingReadyList, +-uxCurrentNumberOfTasks, uxTopUsedPriority. ++uxCurrentNumberOfTasks, uxTopUsedPriority, xSchedulerRunning. + @end raggedright + @item linux symbols + init_task. diff --git a/meta-oe/recipes-devtools/openocd/openocd/0086-target-image-zero-initialize-ELF-segments-up-to-p_me.patch b/meta-oe/recipes-devtools/openocd/openocd/0086-target-image-zero-initialize-ELF-segments-up-to-p_me.patch new file mode 100644 index 000000000..16778959d --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0086-target-image-zero-initialize-ELF-segments-up-to-p_me.patch @@ -0,0 +1,166 @@ +From 047b1a8fc237af480e3bab66a9827a358afd7547 Mon Sep 17 00:00:00 2001 +From: Peter Collingbourne +Date: Wed, 1 Mar 2023 20:20:29 -0800 +Subject: [PATCH] target/image: zero-initialize ELF segments up to p_memsz + +We were previously not zero-initializing ELF segments between p_filesz +and p_memsz (aka BSS). However, this may be necessary depending on the +user's application. Therefore, start doing so. + +Change-Id: I5a743390069583aca7ee276f53afeccf2cac0855 +Signed-off-by: Peter Collingbourne +Reviewed-on: https://review.openocd.org/c/openocd/+/7513 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/target/image.c | 54 +++++++++++++++++++++++++++++----------------- + 1 file changed, 34 insertions(+), 20 deletions(-) + +diff --git a/src/target/image.c b/src/target/image.c +index f8de7a23e..6aa609d39 100644 +--- a/src/target/image.c ++++ b/src/target/image.c +@@ -407,12 +407,10 @@ static int image_elf32_read_headers(struct image *image) + return ERROR_FILEIO_OPERATION_FAILED; + } + +- /* count useful segments (loadable), ignore BSS section */ ++ /* count useful segments (loadable) */ + image->num_sections = 0; + for (i = 0; i < elf->segment_count; i++) +- if ((field32(elf, +- elf->segments32[i].p_type) == PT_LOAD) && +- (field32(elf, elf->segments32[i].p_filesz) != 0)) ++ if (field32(elf, elf->segments32[i].p_type) == PT_LOAD) + image->num_sections++; + + if (image->num_sections == 0) { +@@ -449,10 +447,8 @@ static int image_elf32_read_headers(struct image *image) + } + + for (i = 0, j = 0; i < elf->segment_count; i++) { +- if ((field32(elf, +- elf->segments32[i].p_type) == PT_LOAD) && +- (field32(elf, elf->segments32[i].p_filesz) != 0)) { +- image->sections[j].size = field32(elf, elf->segments32[i].p_filesz); ++ if (field32(elf, elf->segments32[i].p_type) == PT_LOAD) { ++ image->sections[j].size = field32(elf, elf->segments32[i].p_memsz); + if (load_to_vaddr) + image->sections[j].base_address = field32(elf, + elf->segments32[i].p_vaddr); +@@ -532,12 +528,10 @@ static int image_elf64_read_headers(struct image *image) + return ERROR_FILEIO_OPERATION_FAILED; + } + +- /* count useful segments (loadable), ignore BSS section */ ++ /* count useful segments (loadable) */ + image->num_sections = 0; + for (i = 0; i < elf->segment_count; i++) +- if ((field32(elf, +- elf->segments64[i].p_type) == PT_LOAD) && +- (field64(elf, elf->segments64[i].p_filesz) != 0)) ++ if (field32(elf, elf->segments64[i].p_type) == PT_LOAD) + image->num_sections++; + + if (image->num_sections == 0) { +@@ -574,10 +568,8 @@ static int image_elf64_read_headers(struct image *image) + } + + for (i = 0, j = 0; i < elf->segment_count; i++) { +- if ((field32(elf, +- elf->segments64[i].p_type) == PT_LOAD) && +- (field64(elf, elf->segments64[i].p_filesz) != 0)) { +- image->sections[j].size = field64(elf, elf->segments64[i].p_filesz); ++ if (field32(elf, elf->segments64[i].p_type) == PT_LOAD) { ++ image->sections[j].size = field64(elf, elf->segments64[i].p_memsz); + if (load_to_vaddr) + image->sections[j].base_address = field64(elf, + elf->segments64[i].p_vaddr); +@@ -651,6 +643,8 @@ static int image_elf32_read_section(struct image *image, + { + struct image_elf *elf = image->type_private; + Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private; ++ uint32_t filesz = field32(elf, segment->p_filesz); ++ uint32_t memsz = field32(elf, segment->p_memsz); + size_t read_size, really_read; + int retval; + +@@ -659,9 +653,9 @@ static int image_elf32_read_section(struct image *image, + LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size); + + /* read initialized data in current segment if any */ +- if (offset < field32(elf, segment->p_filesz)) { ++ if (offset < filesz) { + /* maximal size present in file for the current segment */ +- read_size = MIN(size, field32(elf, segment->p_filesz) - offset); ++ read_size = MIN(size, filesz - offset); + LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size, + field32(elf, segment->p_offset) + offset); + /* read initialized area of the segment */ +@@ -675,6 +669,8 @@ static int image_elf32_read_section(struct image *image, + LOG_ERROR("cannot read ELF segment content, read failed"); + return retval; + } ++ buffer += read_size; ++ offset += read_size; + size -= read_size; + *size_read += read_size; + /* need more data ? */ +@@ -682,6 +678,13 @@ static int image_elf32_read_section(struct image *image, + return ERROR_OK; + } + ++ /* clear bss in current segment if any */ ++ if (offset >= filesz) { ++ uint32_t memset_size = MIN(size, memsz - filesz); ++ memset(buffer, 0, memset_size); ++ *size_read += memset_size; ++ } ++ + return ERROR_OK; + } + +@@ -694,6 +697,8 @@ static int image_elf64_read_section(struct image *image, + { + struct image_elf *elf = image->type_private; + Elf64_Phdr *segment = (Elf64_Phdr *)image->sections[section].private; ++ uint64_t filesz = field64(elf, segment->p_filesz); ++ uint64_t memsz = field64(elf, segment->p_memsz); + size_t read_size, really_read; + int retval; + +@@ -702,9 +707,9 @@ static int image_elf64_read_section(struct image *image, + LOG_DEBUG("load segment %d at 0x%" TARGET_PRIxADDR " (sz = 0x%" PRIx32 ")", section, offset, size); + + /* read initialized data in current segment if any */ +- if (offset < field64(elf, segment->p_filesz)) { ++ if (offset < filesz) { + /* maximal size present in file for the current segment */ +- read_size = MIN(size, field64(elf, segment->p_filesz) - offset); ++ read_size = MIN(size, filesz - offset); + LOG_DEBUG("read elf: size = 0x%zx at 0x%" TARGET_PRIxADDR "", read_size, + field64(elf, segment->p_offset) + offset); + /* read initialized area of the segment */ +@@ -718,6 +723,8 @@ static int image_elf64_read_section(struct image *image, + LOG_ERROR("cannot read ELF segment content, read failed"); + return retval; + } ++ buffer += read_size; ++ offset += read_size; + size -= read_size; + *size_read += read_size; + /* need more data ? */ +@@ -725,6 +732,13 @@ static int image_elf64_read_section(struct image *image, + return ERROR_OK; + } + ++ /* clear bss in current segment if any */ ++ if (offset >= filesz) { ++ uint64_t memset_size = MIN(size, memsz - filesz); ++ memset(buffer, 0, memset_size); ++ *size_read += memset_size; ++ } ++ + return ERROR_OK; + } + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0087-target-xtensa-add-NX-support.patch b/meta-oe/recipes-devtools/openocd/openocd/0087-target-xtensa-add-NX-support.patch new file mode 100644 index 000000000..ea280eff0 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0087-target-xtensa-add-NX-support.patch @@ -0,0 +1,806 @@ +From 904d58c208ab03f09f8d8e7184d49f42f6e16533 Mon Sep 17 00:00:00 2001 +From: Ian Thompson +Date: Fri, 4 Nov 2022 14:54:24 -0700 +Subject: [PATCH] target/xtensa: add NX support + +- Manual integration of NX support from xt0.2 release +- No new clang static analysis warnings + +Signed-off-by: Ian Thompson +Change-Id: I95b51ccc83e56c0d4dbf09e01969ed6a4a93d497 +Reviewed-on: https://review.openocd.org/c/openocd/+/7356 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/target/xtensa/xtensa.c | 367 ++++++++++++++++++++---- + src/target/xtensa/xtensa.h | 40 +++ + src/target/xtensa/xtensa_debug_module.h | 15 + + 3 files changed, 370 insertions(+), 52 deletions(-) + +diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c +index b57e2d660..fcd00487c 100644 +--- a/src/target/xtensa/xtensa.c ++++ b/src/target/xtensa/xtensa.c +@@ -165,6 +165,7 @@ + #define XT_SR_DDR (xtensa_regs[XT_REG_IDX_DDR].reg_num) + #define XT_SR_PS (xtensa_regs[XT_REG_IDX_PS].reg_num) + #define XT_SR_WB (xtensa_regs[XT_REG_IDX_WINDOWBASE].reg_num) ++#define XT_REG_A0 (xtensa_regs[XT_REG_IDX_AR0].reg_num) + #define XT_REG_A3 (xtensa_regs[XT_REG_IDX_AR3].reg_num) + #define XT_REG_A4 (xtensa_regs[XT_REG_IDX_AR4].reg_num) + +@@ -173,6 +174,7 @@ + #define XT_EPC_REG_NUM_BASE (0xb0U) /* (EPC1 - 1), for adding DBGLEVEL */ + #define XT_PC_REG_NUM_VIRTUAL (0xffU) /* Marker for computing PC (EPC[DBGLEVEL) */ + #define XT_PC_DBREG_NUM_BASE (0x20U) /* External (i.e., GDB) access */ ++#define XT_NX_IBREAKC_BASE (0xc0U) /* (IBREAKC0..IBREAKC1) for NX */ + + #define XT_SW_BREAKPOINTS_MAX_NUM 32 + #define XT_HW_IBREAK_MAX_NUM 2 +@@ -476,7 +478,9 @@ static enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(struct xtensa *x + LOG_ERROR("Error: can't convert register %d to non-windowbased register!", reg_idx); + return -1; + } +- return ((idx + windowbase * 4) & (xtensa->core_config->aregs_num - 1)) + XT_REG_IDX_AR0; ++ /* Each windowbase value represents 4 registers on LX and 8 on NX */ ++ int base_inc = (xtensa->core_config->core_type == XT_LX) ? 4 : 8; ++ return ((idx + windowbase * base_inc) & (xtensa->core_config->aregs_num - 1)) + XT_REG_IDX_AR0; + } + + static enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(struct xtensa *xtensa, +@@ -526,26 +530,29 @@ static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, u + static int xtensa_window_state_save(struct target *target, uint32_t *woe) + { + struct xtensa *xtensa = target_to_xtensa(target); +- int woe_dis; ++ unsigned int woe_sr = (xtensa->core_config->core_type == XT_LX) ? XT_SR_PS : XT_SR_WB; ++ uint32_t woe_dis; + uint8_t woe_buf[4]; + + if (xtensa->core_config->windowed) { +- /* Save PS (LX) and disable window overflow exceptions prior to AR save */ +- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_PS, XT_REG_A3)); ++ /* Save PS (LX) or WB (NX) and disable window overflow exceptions prior to AR save */ ++ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, woe_sr, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, woe_buf); + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (res != ERROR_OK) { +- LOG_ERROR("Failed to read PS (%d)!", res); ++ LOG_TARGET_ERROR(target, "Failed to read %s (%d)!", ++ (woe_sr == XT_SR_PS) ? "PS" : "WB", res); + return res; + } + xtensa_core_status_check(target); + *woe = buf_get_u32(woe_buf, 0, 32); +- woe_dis = *woe & ~XT_PS_WOE_MSK; +- LOG_DEBUG("Clearing PS.WOE (0x%08" PRIx32 " -> 0x%08" PRIx32 ")", *woe, woe_dis); ++ woe_dis = *woe & ~((woe_sr == XT_SR_PS) ? XT_PS_WOE_MSK : XT_WB_S_MSK); ++ LOG_TARGET_DEBUG(target, "Clearing %s (0x%08" PRIx32 " -> 0x%08" PRIx32 ")", ++ (woe_sr == XT_SR_PS) ? "PS.WOE" : "WB.S", *woe, woe_dis); + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe_dis); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); +- xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3)); ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, woe_sr, XT_REG_A3)); + } + return ERROR_OK; + } +@@ -554,12 +561,14 @@ static int xtensa_window_state_save(struct target *target, uint32_t *woe) + static void xtensa_window_state_restore(struct target *target, uint32_t woe) + { + struct xtensa *xtensa = target_to_xtensa(target); ++ unsigned int woe_sr = (xtensa->core_config->core_type == XT_LX) ? XT_SR_PS : XT_SR_WB; + if (xtensa->core_config->windowed) { + /* Restore window overflow exception state */ + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); +- xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3)); +- LOG_DEBUG("Restored PS.WOE (0x%08" PRIx32 ")", woe); ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, woe_sr, XT_REG_A3)); ++ LOG_TARGET_DEBUG(target, "Restored %s (0x%08" PRIx32 ")", ++ (woe_sr == XT_SR_PS) ? "PS.WOE" : "WB", woe); + } + } + +@@ -596,6 +605,10 @@ static int xtensa_write_dirty_registers(struct target *target) + bool preserve_a3 = false; + uint8_t a3_buf[4]; + xtensa_reg_val_t a3 = 0, woe; ++ unsigned int ms_idx = (xtensa->core_config->core_type == XT_NX) ? ++ xtensa->nx_reg_idx[XT_NX_REG_IDX_MS] : reg_list_size; ++ xtensa_reg_val_t ms; ++ bool restore_ms = false; + + LOG_TARGET_DEBUG(target, "start"); + +@@ -627,13 +640,25 @@ static int xtensa_write_dirty_registers(struct target *target) + } else if (rlist[ridx].type == XT_REG_FR) { + xtensa_queue_exec_ins(xtensa, XT_INS_WFR(xtensa, reg_num, XT_REG_A3)); + } else {/*SFR */ +- if (reg_num == XT_PC_REG_NUM_VIRTUAL) +- /* reg number of PC for debug interrupt depends on NDEBUGLEVEL +- **/ +- reg_num = +- (XT_EPC_REG_NUM_BASE + +- xtensa->core_config->debug.irq_level); +- xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3)); ++ if (reg_num == XT_PC_REG_NUM_VIRTUAL) { ++ if (xtensa->core_config->core_type == XT_LX) { ++ /* reg number of PC for debug interrupt depends on NDEBUGLEVEL */ ++ reg_num = (XT_EPC_REG_NUM_BASE + xtensa->core_config->debug.irq_level); ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3)); ++ } else { ++ /* NX PC set through issuing a jump instruction */ ++ xtensa_queue_exec_ins(xtensa, XT_INS_JX(xtensa, XT_REG_A3)); ++ } ++ } else if (i == ms_idx) { ++ /* MS must be restored after ARs. This ensures ARs remain in correct ++ * order even for reversed register groups (overflow/underflow). ++ */ ++ ms = regval; ++ restore_ms = true; ++ LOG_TARGET_DEBUG(target, "Delaying MS write: 0x%x", ms); ++ } else { ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3)); ++ } + } + } + reg_list[i].dirty = false; +@@ -648,12 +673,12 @@ static int xtensa_write_dirty_registers(struct target *target) + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, +- xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, +- XT_REG_A3)); ++ xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, ++ XT_REG_A3)); + reg_list[XT_REG_IDX_CPENABLE].dirty = false; + } + +- preserve_a3 = (xtensa->core_config->windowed); ++ preserve_a3 = (xtensa->core_config->windowed) || (xtensa->core_config->core_type == XT_NX); + if (preserve_a3) { + /* Save (windowed) A3 for scratch use */ + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); +@@ -670,7 +695,12 @@ static int xtensa_write_dirty_registers(struct target *target) + if (res != ERROR_OK) + return res; + /* Grab the windowbase, we need it. */ +- windowbase = xtensa_reg_get(target, XT_REG_IDX_WINDOWBASE); ++ uint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ? ++ XT_REG_IDX_WINDOWBASE : xtensa->nx_reg_idx[XT_NX_REG_IDX_WB]; ++ windowbase = xtensa_reg_get(target, wb_idx); ++ if (xtensa->core_config->core_type == XT_NX) ++ windowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT; ++ + /* Check if there are mismatches between the ARx and corresponding Ax registers. + * When the user sets a register on a windowed config, xt-gdb may set the ARx + * register directly. Thus we take ARx as priority over Ax if both are dirty +@@ -748,10 +778,12 @@ static int xtensa_write_dirty_registers(struct target *target) + } + } + } +- /*Now rotate the window so we'll see the next 16 registers. The final rotate +- * will wraparound, */ +- /*leaving us in the state we were. */ +- xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, 4)); ++ ++ /* Now rotate the window so we'll see the next 16 registers. The final rotate ++ * will wraparound, leaving us in the state we were. ++ * Each ROTW rotates 4 registers on LX and 8 on NX */ ++ int rotw_arg = (xtensa->core_config->core_type == XT_LX) ? 4 : 2; ++ xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, rotw_arg)); + } + + xtensa_window_state_restore(target, woe); +@@ -760,6 +792,14 @@ static int xtensa_write_dirty_registers(struct target *target) + xtensa->scratch_ars[s].intval = false; + } + ++ if (restore_ms) { ++ uint32_t ms_regno = xtensa->optregs[ms_idx - XT_NUM_REGS].reg_num; ++ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, ms); ++ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, ms_regno, XT_REG_A3)); ++ LOG_TARGET_DEBUG(target, "Delayed MS (0x%x) write complete: 0x%x", ms_regno, ms); ++ } ++ + if (preserve_a3) { + xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3); + xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); +@@ -877,10 +917,41 @@ static inline void xtensa_reg_set_value(struct reg *reg, xtensa_reg_val_t value) + reg->dirty = true; + } + ++static int xtensa_imprecise_exception_occurred(struct target *target) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ for (enum xtensa_nx_reg_idx idx = XT_NX_REG_IDX_IEVEC; idx <= XT_NX_REG_IDX_MESR; idx++) { ++ enum xtensa_reg_id ridx = xtensa->nx_reg_idx[idx]; ++ if (xtensa->nx_reg_idx[idx]) { ++ xtensa_reg_val_t reg = xtensa_reg_get(target, xtensa->nx_reg_idx[idx]); ++ if (reg & XT_IMPR_EXC_MSK) { ++ LOG_TARGET_DEBUG(target, "Imprecise exception: %s: 0x%x", ++ xtensa->core_cache->reg_list[ridx].name, reg); ++ return true; ++ } ++ } ++ } ++ return false; ++} ++ ++static void xtensa_imprecise_exception_clear(struct target *target) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ for (enum xtensa_nx_reg_idx idx = XT_NX_REG_IDX_IEVEC; idx <= XT_NX_REG_IDX_MESRCLR; idx++) { ++ enum xtensa_reg_id ridx = xtensa->nx_reg_idx[idx]; ++ if (ridx && idx != XT_NX_REG_IDX_MESR) { ++ xtensa_reg_val_t value = (idx == XT_NX_REG_IDX_MESRCLR) ? XT_MESRCLR_IMPR_EXC_MSK : 0; ++ xtensa_reg_set(target, ridx, value); ++ LOG_TARGET_DEBUG(target, "Imprecise exception: clearing %s (0x%x)", ++ xtensa->core_cache->reg_list[ridx].name, value); ++ } ++ } ++} ++ + int xtensa_core_status_check(struct target *target) + { + struct xtensa *xtensa = target_to_xtensa(target); +- int res, needclear = 0; ++ int res, needclear = 0, needimprclear = 0; + + xtensa_dm_core_status_read(&xtensa->dbg_mod); + xtensa_dsr_t dsr = xtensa_dm_core_status_get(&xtensa->dbg_mod); +@@ -904,11 +975,20 @@ int xtensa_core_status_check(struct target *target) + dsr); + needclear = 1; + } ++ if (xtensa->core_config->core_type == XT_NX && (xtensa_imprecise_exception_occurred(target))) { ++ if (!xtensa->suppress_dsr_errors) ++ LOG_TARGET_ERROR(target, ++ "%s: Imprecise exception occurred!", target_name(target)); ++ needclear = 1; ++ needimprclear = 1; ++ } + if (needclear) { + res = xtensa_dm_core_status_clear(&xtensa->dbg_mod, + OCDDSR_EXECEXCEPTION | OCDDSR_EXECOVERRUN); + if (res != ERROR_OK && !xtensa->suppress_dsr_errors) + LOG_TARGET_ERROR(target, "clearing DSR failed!"); ++ if (xtensa->core_config->core_type == XT_NX && needimprclear) ++ xtensa_imprecise_exception_clear(target); + return ERROR_FAIL; + } + return ERROR_OK; +@@ -934,8 +1014,12 @@ void xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg + void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value) + { + struct xtensa *xtensa = target_to_xtensa(target); ++ uint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ? ++ XT_REG_IDX_WINDOWBASE : xtensa->nx_reg_idx[XT_NX_REG_IDX_WB]; + uint32_t windowbase = (xtensa->core_config->windowed ? +- xtensa_reg_get(target, XT_REG_IDX_WINDOWBASE) : 0); ++ xtensa_reg_get(target, wb_idx) : 0); ++ if (xtensa->core_config->core_type == XT_NX) ++ windowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT; + int ar_idx = xtensa_windowbase_offset_to_canonical(xtensa, a_idx, windowbase); + xtensa_reg_set(target, a_idx, value); + xtensa_reg_set(target, ar_idx, value); +@@ -944,14 +1028,68 @@ void xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, + /* Read cause for entering halted state; return bitmask in DEBUGCAUSE_* format */ + uint32_t xtensa_cause_get(struct target *target) + { +- return xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE); ++ struct xtensa *xtensa = target_to_xtensa(target); ++ if (xtensa->core_config->core_type == XT_LX) { ++ /* LX cause in DEBUGCAUSE */ ++ return xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE); ++ } ++ if (xtensa->nx_stop_cause & DEBUGCAUSE_VALID) ++ return xtensa->nx_stop_cause; ++ ++ /* NX cause determined from DSR.StopCause */ ++ if (xtensa_dm_core_status_read(&xtensa->dbg_mod) != ERROR_OK) { ++ LOG_TARGET_ERROR(target, "Read DSR error"); ++ } else { ++ uint32_t dsr = xtensa_dm_core_status_get(&xtensa->dbg_mod); ++ /* NX causes are prioritized; only 1 bit can be set */ ++ switch ((dsr & OCDDSR_STOPCAUSE) >> OCDDSR_STOPCAUSE_SHIFT) { ++ case OCDDSR_STOPCAUSE_DI: ++ xtensa->nx_stop_cause = DEBUGCAUSE_DI; ++ break; ++ case OCDDSR_STOPCAUSE_SS: ++ xtensa->nx_stop_cause = DEBUGCAUSE_IC; ++ break; ++ case OCDDSR_STOPCAUSE_IB: ++ xtensa->nx_stop_cause = DEBUGCAUSE_IB; ++ break; ++ case OCDDSR_STOPCAUSE_B: ++ case OCDDSR_STOPCAUSE_B1: ++ xtensa->nx_stop_cause = DEBUGCAUSE_BI; ++ break; ++ case OCDDSR_STOPCAUSE_BN: ++ xtensa->nx_stop_cause = DEBUGCAUSE_BN; ++ break; ++ case OCDDSR_STOPCAUSE_DB0: ++ case OCDDSR_STOPCAUSE_DB1: ++ xtensa->nx_stop_cause = DEBUGCAUSE_DB; ++ break; ++ default: ++ LOG_TARGET_ERROR(target, "Unknown stop cause (DSR: 0x%08x)", dsr); ++ break; ++ } ++ if (xtensa->nx_stop_cause) ++ xtensa->nx_stop_cause |= DEBUGCAUSE_VALID; ++ } ++ return xtensa->nx_stop_cause; + } + + void xtensa_cause_clear(struct target *target) + { + struct xtensa *xtensa = target_to_xtensa(target); +- xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); +- xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false; ++ if (xtensa->core_config->core_type == XT_LX) { ++ xtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0); ++ xtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false; ++ } else { ++ /* NX DSR.STOPCAUSE is not writeable; clear cached copy but leave it valid */ ++ xtensa->nx_stop_cause = DEBUGCAUSE_VALID; ++ } ++} ++ ++void xtensa_cause_reset(struct target *target) ++{ ++ /* Clear DEBUGCAUSE_VALID to trigger re-read (on NX) */ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ xtensa->nx_stop_cause = 0; + } + + int xtensa_assert_reset(struct target *target) +@@ -1008,9 +1146,11 @@ int xtensa_fetch_all_regs(struct target *target) + struct xtensa *xtensa = target_to_xtensa(target); + struct reg *reg_list = xtensa->core_cache->reg_list; + unsigned int reg_list_size = xtensa->core_cache->num_regs; +- xtensa_reg_val_t cpenable = 0, windowbase = 0, a3; ++ xtensa_reg_val_t cpenable = 0, windowbase = 0, a0 = 0, a3; ++ unsigned int ms_idx = reg_list_size; ++ uint32_t ms = 0; + uint32_t woe; +- uint8_t a3_buf[4]; ++ uint8_t a0_buf[4], a3_buf[4], ms_buf[4]; + bool debug_dsrs = !xtensa->regs_fetched || LOG_LEVEL_IS(LOG_LVL_DEBUG); + + union xtensa_reg_val_u *regvals = calloc(reg_list_size, sizeof(*regvals)); +@@ -1030,6 +1170,25 @@ int xtensa_fetch_all_regs(struct target *target) + /* Save (windowed) A3 so cache matches physical AR3; A3 usable as scratch */ + xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf); ++ if (xtensa->core_config->core_type == XT_NX) { ++ /* Save (windowed) A0 as well--it will be required for reading PC */ ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A0)); ++ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a0_buf); ++ ++ /* Set MS.DispSt, clear MS.DE prior to accessing ARs. This ensures ARs remain ++ * in correct order even for reversed register groups (overflow/underflow). ++ */ ++ ms_idx = xtensa->nx_reg_idx[XT_NX_REG_IDX_MS]; ++ uint32_t ms_regno = xtensa->optregs[ms_idx - XT_NUM_REGS].reg_num; ++ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, ms_regno, XT_REG_A3)); ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3)); ++ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, ms_buf); ++ LOG_TARGET_DEBUG(target, "Overriding MS (0x%x): 0x%x", ms_regno, XT_MS_DISPST_DBG); ++ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, XT_MS_DISPST_DBG); ++ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, ms_regno, XT_REG_A3)); ++ } ++ + int res = xtensa_window_state_save(target, &woe); + if (res != ERROR_OK) + goto xtensa_fetch_all_regs_done; +@@ -1052,11 +1211,13 @@ int xtensa_fetch_all_regs(struct target *target) + dsrs[XT_REG_IDX_AR0 + i + j].buf); + } + } +- if (xtensa->core_config->windowed) ++ if (xtensa->core_config->windowed) { + /* Now rotate the window so we'll see the next 16 registers. The final rotate +- * will wraparound, */ +- /* leaving us in the state we were. */ +- xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, 4)); ++ * will wraparound, leaving us in the state we were. ++ * Each ROTW rotates 4 registers on LX and 8 on NX */ ++ int rotw_arg = (xtensa->core_config->core_type == XT_LX) ? 4 : 2; ++ xtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, rotw_arg)); ++ } + } + xtensa_window_state_restore(target, woe); + +@@ -1074,6 +1235,10 @@ int xtensa_fetch_all_regs(struct target *target) + xtensa_core_status_check(target); + + a3 = buf_get_u32(a3_buf, 0, 32); ++ if (xtensa->core_config->core_type == XT_NX) { ++ a0 = buf_get_u32(a0_buf, 0, 32); ++ ms = buf_get_u32(ms_buf, 0, 32); ++ } + + if (xtensa->core_config->coproc) { + cpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE].buf, 0, 32); +@@ -1104,17 +1269,30 @@ int xtensa_fetch_all_regs(struct target *target) + break; + case XT_REG_SPECIAL: + if (reg_num == XT_PC_REG_NUM_VIRTUAL) { +- /* reg number of PC for debug interrupt depends on NDEBUGLEVEL */ +- reg_num = XT_EPC_REG_NUM_BASE + xtensa->core_config->debug.irq_level; +- } else if (reg_num == xtensa_regs[XT_REG_IDX_PS].reg_num) { ++ if (xtensa->core_config->core_type == XT_LX) { ++ /* reg number of PC for debug interrupt depends on NDEBUGLEVEL */ ++ reg_num = XT_EPC_REG_NUM_BASE + xtensa->core_config->debug.irq_level; ++ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3)); ++ } else { ++ /* NX PC read through CALL0(0) and reading A0 */ ++ xtensa_queue_exec_ins(xtensa, XT_INS_CALL0(xtensa, 0)); ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A0)); ++ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf); ++ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR, dsrs[i].buf); ++ reg_fetched = false; ++ } ++ } else if ((xtensa->core_config->core_type == XT_LX) ++ && (reg_num == xtensa_regs[XT_REG_IDX_PS].reg_num)) { + /* reg number of PS for debug interrupt depends on NDEBUGLEVEL */ + reg_num = XT_EPS_REG_NUM_BASE + xtensa->core_config->debug.irq_level; ++ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3)); + } else if (reg_num == xtensa_regs[XT_REG_IDX_CPENABLE].reg_num) { + /* CPENABLE already read/updated; don't re-read */ + reg_fetched = false; + break; ++ } else { ++ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3)); + } +- xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3)); + break; + default: + reg_fetched = false; +@@ -1154,9 +1332,15 @@ int xtensa_fetch_all_regs(struct target *target) + } + } + +- if (xtensa->core_config->windowed) ++ if (xtensa->core_config->windowed) { + /* We need the windowbase to decode the general addresses. */ +- windowbase = buf_get_u32(regvals[XT_REG_IDX_WINDOWBASE].buf, 0, 32); ++ uint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ? ++ XT_REG_IDX_WINDOWBASE : xtensa->nx_reg_idx[XT_NX_REG_IDX_WB]; ++ windowbase = buf_get_u32(regvals[wb_idx].buf, 0, 32); ++ if (xtensa->core_config->core_type == XT_NX) ++ windowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT; ++ } ++ + /* Decode the result and update the cache. */ + for (unsigned int i = 0; i < reg_list_size; i++) { + struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs; +@@ -1180,6 +1364,16 @@ int xtensa_fetch_all_regs(struct target *target) + bool is_dirty = (i == XT_REG_IDX_CPENABLE); + if (xtensa_extra_debug_log) + LOG_INFO("Register %s: 0x%X", reg_list[i].name, regval); ++ if (rlist[ridx].reg_num == XT_PC_REG_NUM_VIRTUAL && ++ xtensa->core_config->core_type == XT_NX) { ++ /* A0 from prior CALL0 points to next instruction; decrement it */ ++ regval -= 3; ++ is_dirty = 1; ++ } else if (i == ms_idx) { ++ LOG_TARGET_DEBUG(target, "Caching MS: 0x%x", ms); ++ regval = ms; ++ is_dirty = 1; ++ } + xtensa_reg_set(target, i, regval); + reg_list[i].dirty = is_dirty; /*always do this _after_ xtensa_reg_set! */ + } +@@ -1214,6 +1408,11 @@ int xtensa_fetch_all_regs(struct target *target) + /* We have used A3 (XT_REG_RELGEN) as a scratch register. Restore and flag for write-back. */ + xtensa_reg_set(target, XT_REG_IDX_A3, a3); + xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3); ++ if (xtensa->core_config->core_type == XT_NX) { ++ xtensa_reg_set(target, XT_REG_IDX_A0, a0); ++ xtensa_mark_register_dirty(xtensa, XT_REG_IDX_A0); ++ } ++ + xtensa->regs_fetched = true; + xtensa_fetch_all_regs_done: + free(regvals); +@@ -1262,7 +1461,7 @@ int xtensa_get_gdb_reg_list(struct target *target, + struct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs; + unsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS; + int sparse_idx = rlist[ridx].dbreg_num; +- if (i == XT_REG_IDX_PS) { ++ if (i == XT_REG_IDX_PS && xtensa->core_config->core_type == XT_LX) { + if (xtensa->eps_dbglevel_idx == 0) { + LOG_ERROR("eps_dbglevel_idx not set\n"); + return ERROR_FAIL; +@@ -1372,10 +1571,13 @@ int xtensa_prepare_resume(struct target *target, + if (xtensa->hw_brps[slot]) { + /* Write IBREAKA[slot] and set bit #slot in IBREAKENABLE */ + xtensa_reg_set(target, XT_REG_IDX_IBREAKA0 + slot, xtensa->hw_brps[slot]->address); ++ if (xtensa->core_config->core_type == XT_NX) ++ xtensa_reg_set(target, xtensa->nx_reg_idx[XT_NX_REG_IDX_IBREAKC0] + slot, XT_IBREAKC_FB); + bpena |= BIT(slot); + } + } +- xtensa_reg_set(target, XT_REG_IDX_IBREAKENABLE, bpena); ++ if (xtensa->core_config->core_type == XT_LX) ++ xtensa_reg_set(target, XT_REG_IDX_IBREAKENABLE, bpena); + + /* Here we write all registers to the targets */ + int res = xtensa_write_dirty_registers(target); +@@ -1390,6 +1592,7 @@ int xtensa_do_resume(struct target *target) + + LOG_TARGET_DEBUG(target, "start"); + ++ xtensa_cause_reset(target); + xtensa_queue_exec_ins(xtensa, XT_INS_RFDO(xtensa)); + int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (res != ERROR_OK) { +@@ -1467,13 +1670,14 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in + return ERROR_TARGET_NOT_HALTED; + } + +- if (xtensa->eps_dbglevel_idx == 0) { +- LOG_ERROR("eps_dbglevel_idx not set\n"); ++ if (xtensa->eps_dbglevel_idx == 0 && xtensa->core_config->core_type == XT_LX) { ++ LOG_TARGET_ERROR(target, "eps_dbglevel_idx not set\n"); + return ERROR_FAIL; + } + + /* Save old ps (EPS[dbglvl] on LX), pc */ +- oldps = xtensa_reg_get(target, xtensa->eps_dbglevel_idx); ++ oldps = xtensa_reg_get(target, (xtensa->core_config->core_type == XT_LX) ? ++ xtensa->eps_dbglevel_idx : XT_REG_IDX_PS); + oldpc = xtensa_reg_get(target, XT_REG_IDX_PC); + + cause = xtensa_cause_get(target); +@@ -1542,7 +1746,7 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in + if (!handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) + /* handle normal SW breakpoint */ + xtensa_cause_clear(target); /* so we don't recurse into the same routine */ +- if ((oldps & 0xf) >= icountlvl) { ++ if (xtensa->core_config->core_type == XT_LX && ((oldps & 0xf) >= icountlvl)) { + /* Lower interrupt level to allow stepping, but flag eps[dbglvl] to be restored */ + ps_lowered = true; + uint32_t newps = (oldps & ~0xf) | (icountlvl - 1); +@@ -1554,10 +1758,16 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in + oldps); + } + do { +- xtensa_reg_set(target, XT_REG_IDX_ICOUNTLEVEL, icountlvl); +- xtensa_reg_set(target, XT_REG_IDX_ICOUNT, icount_val); ++ if (xtensa->core_config->core_type == XT_LX) { ++ xtensa_reg_set(target, XT_REG_IDX_ICOUNTLEVEL, icountlvl); ++ xtensa_reg_set(target, XT_REG_IDX_ICOUNT, icount_val); ++ } else { ++ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, OCDDCR_STEPREQUEST); ++ } + +- /* Now ICOUNT is set, we can resume as if we were going to run */ ++ /* Now that ICOUNT (LX) or DCR.StepRequest (NX) is set, ++ * we can resume as if we were going to run ++ */ + res = xtensa_prepare_resume(target, current, address, 0, 0); + if (res != ERROR_OK) { + LOG_TARGET_ERROR(target, "Failed to prepare resume for single step"); +@@ -2108,6 +2318,22 @@ int xtensa_poll(struct target *target) + OCDDSR_DEBUGPENDBREAK | OCDDSR_DEBUGINTBREAK | OCDDSR_DEBUGPENDTRAX | + OCDDSR_DEBUGINTTRAX | + OCDDSR_DEBUGPENDHOST | OCDDSR_DEBUGINTHOST); ++ if (xtensa->core_config->core_type == XT_NX) { ++ /* Enable imprecise exceptions while in halted state */ ++ xtensa_reg_val_t ps = xtensa_reg_get(target, XT_REG_IDX_PS); ++ xtensa_reg_val_t newps = ps & ~(XT_PS_DIEXC_MSK); ++ xtensa_mark_register_dirty(xtensa, XT_REG_IDX_PS); ++ LOG_TARGET_DEBUG(target, "Enabling PS.DIEXC: 0x%08x -> 0x%08x", ps, newps); ++ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, newps); ++ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3)); ++ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3)); ++ res = xtensa_dm_queue_execute(&xtensa->dbg_mod); ++ if (res != ERROR_OK) { ++ LOG_TARGET_ERROR(target, "Failed to write PS.DIEXC (%d)!", res); ++ return res; ++ } ++ xtensa_core_status_check(target); ++ } + } + } else { + target->debug_reason = DBG_REASON_NOTHALTED; +@@ -2326,6 +2552,8 @@ int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoin + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + xtensa->hw_brps[slot] = NULL; ++ if (xtensa->core_config->core_type == XT_NX) ++ xtensa_reg_set(target, xtensa->nx_reg_idx[XT_NX_REG_IDX_IBREAKC0] + slot, 0); + LOG_TARGET_DEBUG(target, "cleared HW breakpoint %u @ " TARGET_ADDR_FMT, slot, breakpoint->address); + return ERROR_OK; + } +@@ -3073,8 +3301,10 @@ COMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa) + const char *core_name = CMD_ARGV[0]; + if (strcasecmp(core_name, "LX") == 0) { + xtensa->core_config->core_type = XT_LX; ++ } else if (strcasecmp(core_name, "NX") == 0) { ++ xtensa->core_config->core_type = XT_NX; + } else { +- LOG_ERROR("xtdef [LX]\n"); ++ LOG_ERROR("xtdef [LX|NX]\n"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + return ERROR_OK; +@@ -3456,6 +3686,33 @@ COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa) + xtensa->eps_dbglevel_idx = XT_NUM_REGS + xtensa->num_optregs - 1; + LOG_DEBUG("Setting PS (%s) index to %d", rptr->name, xtensa->eps_dbglevel_idx); + } ++ if (xtensa->core_config->core_type == XT_NX) { ++ enum xtensa_nx_reg_idx idx = XT_NX_REG_IDX_NUM; ++ if (strcmp(rptr->name, "ibreakc0") == 0) ++ idx = XT_NX_REG_IDX_IBREAKC0; ++ else if (strcmp(rptr->name, "wb") == 0) ++ idx = XT_NX_REG_IDX_WB; ++ else if (strcmp(rptr->name, "ms") == 0) ++ idx = XT_NX_REG_IDX_MS; ++ else if (strcmp(rptr->name, "ievec") == 0) ++ idx = XT_NX_REG_IDX_IEVEC; ++ else if (strcmp(rptr->name, "ieextern") == 0) ++ idx = XT_NX_REG_IDX_IEEXTERN; ++ else if (strcmp(rptr->name, "mesr") == 0) ++ idx = XT_NX_REG_IDX_MESR; ++ else if (strcmp(rptr->name, "mesrclr") == 0) ++ idx = XT_NX_REG_IDX_MESRCLR; ++ if (idx < XT_NX_REG_IDX_NUM) { ++ if (xtensa->nx_reg_idx[idx] != 0) { ++ LOG_ERROR("nx_reg_idx[%d] previously set to %d", ++ idx, xtensa->nx_reg_idx[idx]); ++ return ERROR_FAIL; ++ } ++ xtensa->nx_reg_idx[idx] = XT_NUM_REGS + xtensa->num_optregs - 1; ++ LOG_DEBUG("NX reg %s: index %d (%d)", ++ rptr->name, xtensa->nx_reg_idx[idx], idx); ++ } ++ } + } else if (strcmp(rptr->name, "cpenable") == 0) { + xtensa->core_config->coproc = true; + } +@@ -3640,6 +3897,12 @@ COMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa) + command_print(CMD, "Current ISR step mode: %s", st); + return ERROR_OK; + } ++ ++ if (xtensa->core_config->core_type == XT_NX) { ++ command_print(CMD, "ERROR: ISR step mode only supported on Xtensa LX"); ++ return ERROR_FAIL; ++ } ++ + /* Masking is ON -> interrupts during stepping are OFF, and vice versa */ + if (!strcasecmp(CMD_ARGV[0], "off")) + state = XT_STEPPING_ISR_ON; +diff --git a/src/target/xtensa/xtensa.h b/src/target/xtensa/xtensa.h +index 4d98f3a36..4216ae24f 100644 +--- a/src/target/xtensa/xtensa.h ++++ b/src/target/xtensa/xtensa.h +@@ -35,6 +35,7 @@ + + #define XT_ISNS_SZ_MAX 3 + ++/* PS register bits (LX) */ + #define XT_PS_RING(_v_) ((uint32_t)((_v_) & 0x3) << 6) + #define XT_PS_RING_MSK (0x3 << 6) + #define XT_PS_RING_GET(_v_) (((_v_) >> 6) & 0x3) +@@ -42,6 +43,31 @@ + #define XT_PS_OWB_MSK (0xF << 8) + #define XT_PS_WOE_MSK BIT(18) + ++/* PS register bits (NX) */ ++#define XT_PS_DIEXC_MSK BIT(2) ++ ++/* MS register bits (NX) */ ++#define XT_MS_DE_MSK BIT(5) ++#define XT_MS_DISPST_MSK (0x1f) ++#define XT_MS_DISPST_DBG (0x10) ++ ++/* WB register bits (NX) */ ++#define XT_WB_P_SHIFT (0) ++#define XT_WB_P_MSK (0x7U << XT_WB_P_SHIFT) ++#define XT_WB_C_SHIFT (4) ++#define XT_WB_C_MSK (0x7U << XT_WB_C_SHIFT) ++#define XT_WB_N_SHIFT (8) ++#define XT_WB_N_MSK (0x7U << XT_WB_N_SHIFT) ++#define XT_WB_S_SHIFT (30) ++#define XT_WB_S_MSK (0x3U << XT_WB_S_SHIFT) ++ ++/* IBREAKC register bits (NX) */ ++#define XT_IBREAKC_FB (0x80000000) ++ ++/* Definitions for imprecise exception registers (NX) */ ++#define XT_IMPR_EXC_MSK (0x00000013) ++#define XT_MESRCLR_IMPR_EXC_MSK (0x00000090) ++ + #define XT_LOCAL_MEM_REGIONS_NUM_MAX 8 + + #define XT_AREGS_NUM_MAX 64 +@@ -79,6 +105,7 @@ struct xtensa_keyval_info_s { + enum xtensa_type { + XT_UNDEF = 0, + XT_LX, ++ XT_NX, + }; + + struct xtensa_cache_config { +@@ -167,6 +194,17 @@ enum xtensa_stepping_isr_mode { + XT_STEPPING_ISR_ON, /* interrupts are enabled during stepping */ + }; + ++enum xtensa_nx_reg_idx { ++ XT_NX_REG_IDX_IBREAKC0 = 0, ++ XT_NX_REG_IDX_WB, ++ XT_NX_REG_IDX_MS, ++ XT_NX_REG_IDX_IEVEC, /* IEVEC, IEEXTERN, and MESR must be contiguous */ ++ XT_NX_REG_IDX_IEEXTERN, ++ XT_NX_REG_IDX_MESR, ++ XT_NX_REG_IDX_MESRCLR, ++ XT_NX_REG_IDX_NUM ++}; ++ + /* Only supported in cores with in-CPU MMU. None of Espressif chips as of now. */ + enum xtensa_mode { + XT_MODE_RING0, +@@ -232,6 +270,8 @@ struct xtensa { + uint8_t come_online_probes_num; + bool proc_syscall; + bool halt_request; ++ uint32_t nx_stop_cause; ++ uint32_t nx_reg_idx[XT_NX_REG_IDX_NUM]; + struct xtensa_keyval_info_s scratch_ars[XT_AR_SCRATCH_NUM]; + bool regs_fetched; /* true after first register fetch completed successfully */ + }; +diff --git a/src/target/xtensa/xtensa_debug_module.h b/src/target/xtensa/xtensa_debug_module.h +index b382e03db..46b29354c 100644 +--- a/src/target/xtensa/xtensa_debug_module.h ++++ b/src/target/xtensa/xtensa_debug_module.h +@@ -246,6 +246,7 @@ struct xtensa_dm_reg_offsets { + #define OCDDCR_ENABLEOCD BIT(0) + #define OCDDCR_DEBUGINTERRUPT BIT(1) + #define OCDDCR_INTERRUPTALLCONDS BIT(2) ++#define OCDDCR_STEPREQUEST BIT(3) /* NX only */ + #define OCDDCR_BREAKINEN BIT(16) + #define OCDDCR_BREAKOUTEN BIT(17) + #define OCDDCR_DEBUGSWACTIVE BIT(20) +@@ -259,6 +260,8 @@ struct xtensa_dm_reg_offsets { + #define OCDDSR_EXECBUSY BIT(2) + #define OCDDSR_EXECOVERRUN BIT(3) + #define OCDDSR_STOPPED BIT(4) ++#define OCDDSR_STOPCAUSE (0xF << 5) /* NX only */ ++#define OCDDSR_STOPCAUSE_SHIFT (5) /* NX only */ + #define OCDDSR_COREWROTEDDR BIT(10) + #define OCDDSR_COREREADDDR BIT(11) + #define OCDDSR_HOSTWROTEDDR BIT(14) +@@ -275,12 +278,24 @@ struct xtensa_dm_reg_offsets { + #define OCDDSR_BREAKINITI BIT(26) + #define OCDDSR_DBGMODPOWERON BIT(31) + ++/* NX stop cause */ ++#define OCDDSR_STOPCAUSE_DI (0) /* Debug Interrupt */ ++#define OCDDSR_STOPCAUSE_SS (1) /* Single-step completed */ ++#define OCDDSR_STOPCAUSE_IB (2) /* HW breakpoint (IBREAKn match) */ ++#define OCDDSR_STOPCAUSE_B1 (4) /* SW breakpoint (BREAK.1 instruction) */ ++#define OCDDSR_STOPCAUSE_BN (5) /* SW breakpoint (BREAK.N instruction) */ ++#define OCDDSR_STOPCAUSE_B (6) /* SW breakpoint (BREAK instruction) */ ++#define OCDDSR_STOPCAUSE_DB0 (8) /* HW watchpoint (DBREAK0 match) */ ++#define OCDDSR_STOPCAUSE_DB1 (9) /* HW watchpoint (DBREAK0 match) */ ++ ++/* LX stop cause */ + #define DEBUGCAUSE_IC BIT(0) /* ICOUNT exception */ + #define DEBUGCAUSE_IB BIT(1) /* IBREAK exception */ + #define DEBUGCAUSE_DB BIT(2) /* DBREAK exception */ + #define DEBUGCAUSE_BI BIT(3) /* BREAK instruction encountered */ + #define DEBUGCAUSE_BN BIT(4) /* BREAK.N instruction encountered */ + #define DEBUGCAUSE_DI BIT(5) /* Debug Interrupt */ ++#define DEBUGCAUSE_VALID BIT(31) /* Pseudo-value to trigger reread (NX only) */ + + #define TRAXCTRL_TREN BIT(0) /* Trace enable. Tracing starts on 0->1 */ + #define TRAXCTRL_TRSTP BIT(1) /* Trace Stop. Make 1 to stop trace. */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0088-helper-add-compiler.h-to-handle-compiler-specific-wo.patch b/meta-oe/recipes-devtools/openocd/openocd/0088-helper-add-compiler.h-to-handle-compiler-specific-wo.patch new file mode 100644 index 000000000..b6c6c6f91 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0088-helper-add-compiler.h-to-handle-compiler-specific-wo.patch @@ -0,0 +1,111 @@ +From e8f376e3c1874ccd14e148164d9695a93c575def Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sat, 4 Mar 2023 23:56:35 +0100 +Subject: [PATCH] helper: add compiler.h to handle compiler specific + workarounds + +Not all compilers nor compiler versions supports the attributes +used in OpenOCD code. +Collect in a single file the workaround to handle them. + +Change-Id: I92d871337281169134ce8e40b2064591518be71f +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7519 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/helper/Makefile.am | 3 ++- + src/helper/compiler.h | 44 ++++++++++++++++++++++++++++++++++++++++++ + src/helper/nvp.h | 6 ++++-- + 3 files changed, 50 insertions(+), 3 deletions(-) + create mode 100644 src/helper/compiler.h + +diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am +index e9c05cfc5..e0fa331ea 100644 +--- a/src/helper/Makefile.am ++++ b/src/helper/Makefile.am +@@ -34,7 +34,8 @@ noinst_LTLIBRARIES += %D%/libhelper.la + %D%/jep106.h \ + %D%/jep106.inc \ + %D%/jim-nvp.h \ +- %D%/nvp.h ++ %D%/nvp.h \ ++ %D%/compiler.h + + STARTUP_TCL_SRCS += %D%/startup.tcl + EXTRA_DIST += \ +diff --git a/src/helper/compiler.h b/src/helper/compiler.h +new file mode 100644 +index 000000000..8f6c09950 +--- /dev/null ++++ b/src/helper/compiler.h +@@ -0,0 +1,44 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++/* ++ * This file contains compiler specific workarounds to handle different ++ * compilers and different compiler versions. ++ * Inspired by Linux's include/linux/compiler_attributes.h ++ * and file sys/cdefs.h in libc and newlib. ++ */ ++ ++#ifndef OPENOCD_HELPER_COMPILER_H ++#define OPENOCD_HELPER_COMPILER_H ++ ++/* ++ * __has_attribute is supported on gcc >= 5, clang >= 2.9 and icc >= 17. ++ */ ++#ifndef __has_attribute ++# define __has_attribute(x) 0 ++#endif ++ ++/* ++ * The __returns_nonnull function attribute marks the return type of the function ++ * as always being non-null. ++ */ ++#ifndef __returns_nonnull ++# if __has_attribute(__returns_nonnull__) ++# define __returns_nonnull __attribute__((__returns_nonnull__)) ++# else ++# define __returns_nonnull ++# endif ++#endif ++ ++/* ++ * The __nonnull function attribute marks pointer parameters that ++ * must not be NULL. ++ */ ++#ifndef __nonnull ++# if __has_attribute(__nonnull__) ++# define __nonnull(params) __attribute__ ((__nonnull__ params)) ++# else ++# define __nonnull(params) ++# endif ++#endif ++ ++#endif /* OPENOCD_HELPER_COMPILER_H */ +diff --git a/src/helper/nvp.h b/src/helper/nvp.h +index 125164e4e..14bd9b028 100644 +--- a/src/helper/nvp.h ++++ b/src/helper/nvp.h +@@ -20,6 +20,8 @@ + #ifndef OPENOCD_HELPER_NVP_H + #define OPENOCD_HELPER_NVP_H + ++#include ++ + /** Name Value Pairs, aka: NVP + * - Given a string - return the associated int. + * - Given a number - return the associated string. +@@ -65,9 +67,9 @@ struct command_invocation; + + /* Name Value Pairs Operations */ + const struct nvp *nvp_name2value(const struct nvp *nvp_table, const char *name) +- __attribute__((returns_nonnull, nonnull(1))); ++ __returns_nonnull __nonnull((1)); + const struct nvp *nvp_value2name(const struct nvp *nvp_table, int v) +- __attribute__((returns_nonnull, nonnull(1))); ++ __returns_nonnull __nonnull((1)); + + void nvp_unknown_command_print(struct command_invocation *cmd, const struct nvp *nvp, + const char *param_name, const char *param_value); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0089-openocd-drop-JIM_EMBEDDED-macro.patch b/meta-oe/recipes-devtools/openocd/openocd/0089-openocd-drop-JIM_EMBEDDED-macro.patch new file mode 100644 index 000000000..577db87ac --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0089-openocd-drop-JIM_EMBEDDED-macro.patch @@ -0,0 +1,35 @@ +From 642735449a3a7297126a3dd9b76ffaaca74a1752 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sat, 4 Mar 2023 19:19:16 +0100 +Subject: [PATCH] openocd: drop JIM_EMBEDDED macro + +The macro JIM_EMBEDDED was required to be defined before including +jim.h in applications that embed jimtcl. +This requirement has been dropped in 2010 by removing the file +dos/Embedder-HOWTO.txt from jimtcl in +https://github.com/msteveb/jimtcl/commit/2d8564100c86#diff-3e93fa55e666 + +Drop the macro definition and the comment that mandates it. + +Change-Id: I36883f60f25bb25839e4ebf908159569659764dd +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7518 +Tested-by: jenkins +--- + src/helper/command.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/helper/command.c b/src/helper/command.c +index 12434ec90..b358e18aa 100644 +--- a/src/helper/command.c ++++ b/src/helper/command.c +@@ -18,9 +18,6 @@ + #include "config.h" + #endif + +-/* see Embedded-HOWTO.txt in Jim Tcl project hosted on BerliOS*/ +-#define JIM_EMBEDDED +- + /* @todo the inclusion of target.h here is a layering violation */ + #include + #include diff --git a/meta-oe/recipes-devtools/openocd/openocd/0090-build-fix-distcheck-for-jimtcl.patch b/meta-oe/recipes-devtools/openocd/openocd/0090-build-fix-distcheck-for-jimtcl.patch new file mode 100644 index 000000000..7adfdb295 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0090-build-fix-distcheck-for-jimtcl.patch @@ -0,0 +1,81 @@ +From 45eeeab3080991168a07854af5dded926a22253c Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 6 Mar 2023 00:27:58 +0100 +Subject: [PATCH] build: fix distcheck for jimtcl + +The issues have been highlighted while integrated jimtcl 0.82, +but were already present. + +While building jimtcl as submodule, OpenOCD generates the file +jimtcl/configure.gnu to pass specific configure flags. +Issue 1: this file is not included in the distribution. +This causes the rebuild from the distribution to have a jimtcl +built with different (the default) configure flags. +With jimtcl 0.82 the new default is to enable all the features, +but a bug causes the build to fail when openssl is not installed +in the build system (the bug is already fixed but after 0.82 [1]). +All these together cause OpenOCD Jenkins to fail the build for +target 'distcheck' with jimtcl 0.82. + +Add jimtcl/configure.gnu to OpenOCD distribution's file list. + +The build system considers jimtcl/configure.gnu as a temporarily +file that should be removed during 'distclean'. +Issue 2: 'distcheck' set read-only permission to the source files, +including jimtcl/configure.gnu, so 'distclean' fails removing it. + +Add a leading '-' to ignore errors while trying to remove the +file. + +Issue 3: Now that 'distcheck' properly configures and builds +jimtcl, 'distcheck' still fails because we have enabled jimtcl +json support in [2] and jimtcl 'distclean' fails to properly +remove one object file (fixed after 0.82 [3]). + +Make OpenOCD removing the file jimtcl/jsmn/jsmn.o to complete +the execution of 'distcheck'. Add a comment specifying which of +the jimtcl versions are affected. + +Change-Id: I2f9153c5a41ba66b989b27c7bc57b38d1744cc29 +Signed-off-by: Antonio Borneo +Link: [1] https://github.com/msteveb/jimtcl/commit/22277943a19c +Link: [2] 0a36acbf6ac6 ("configure: build jimtcl with json extension") +Link: [3] https://github.com/msteveb/jimtcl/commit/32a488587a3e +Reviewed-on: https://review.openocd.org/c/openocd/+/7527 +Tested-by: jenkins +Reviewed-by: zapb +--- + Makefile.am | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 41daf9522..fa92da912 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -26,10 +26,14 @@ noinst_LTLIBRARIES = + info_TEXINFOS = + dist_man_MANS = + EXTRA_DIST = ++DISTCLEANFILES = + + if INTERNAL_JIMTCL + SUBDIRS += jimtcl + DIST_SUBDIRS += jimtcl ++EXTRA_DIST += jimtcl/configure.gnu ++# jimtcl from 0.79 to 0.82 miss cleaning jsmn.o ++DISTCLEANFILES += jimtcl/jsmn/jsmn.o + endif + + # common flags used in openocd build +@@ -129,9 +133,9 @@ uninstall-hook: + + distclean-local: + rm -rf Doxyfile doxygen +- rm -f $(srcdir)/jimtcl/configure.gnu ++ -rm -f $(srcdir)/jimtcl/configure.gnu + +-DISTCLEANFILES = doxygen.log ++DISTCLEANFILES += doxygen.log + + METASOURCES = AUTO + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0091-jimtcl-update-to-version-0.82.patch b/meta-oe/recipes-devtools/openocd/openocd/0091-jimtcl-update-to-version-0.82.patch new file mode 100644 index 000000000..1d729e7a0 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0091-jimtcl-update-to-version-0.82.patch @@ -0,0 +1,53 @@ +From dccf323c1f78d015f75db4cef8cdc33523e1abd6 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sat, 4 Mar 2023 12:08:58 +0100 +Subject: [PATCH] jimtcl: update to version 0.82 + +The new version modifies it's auto configure in change + https://github.com/msteveb/jimtcl/commit/ccd47be13019 +stating: + configure: Default to --full + Now use --minimal and/or --without-ext to disable things. + +With such change jimtcl doesn't build anymore as OpenOCD submodule +because of errors linking with new dependencies openssl and zlib. + +Use option --minimal to keep the same build configuration as with +former jimtcl 0.81. +Add option --disable-ssl to avoid a build error on system with no +ssl libraries installed. This is already fixed in jimtcl upstream +but not part of 0.82. Note that ssl is not currently used by +OpenOCD. + +Change-Id: I0879891dbd083bfbff1e904daf6cd549c3329bbf +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7517 +Tested-by: jenkins +--- + configure.ac | 4 ++-- + jimtcl | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index cc7139c7c..ac2808e1f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -571,9 +571,9 @@ AS_IF([test "x$enable_buspirate" != "xno"], [ + AS_IF([test "x$use_internal_jimtcl" = "xyes"], [ + AS_IF([test -f "$srcdir/jimtcl/configure"], [ + AS_IF([test "x$use_internal_jimtcl_maintainer" = "xyes"], [ +- jimtcl_config_options="--disable-install-jim --with-ext=json --maintainer" ++ jimtcl_config_options="--disable-install-jim --with-ext=json --minimal --disable-ssl --maintainer" + ], [ +- jimtcl_config_options="--disable-install-jim --with-ext=json" ++ jimtcl_config_options="--disable-install-jim --with-ext=json --minimal --disable-ssl" + ]) + AX_CONFIG_SUBDIR_OPTION([jimtcl], [$jimtcl_config_options]) + ], [ +diff --git a/jimtcl b/jimtcl +index a77ef1a62..1933e5457 160000 +--- a/jimtcl ++++ b/jimtcl +@@ -1 +1 @@ +-Subproject commit a77ef1a6218fad4c928ddbdc03c1aedc41007e70 ++Subproject commit 1933e5457b9512d39ebbe11ed32578aada149f49 diff --git a/meta-oe/recipes-devtools/openocd/openocd/0092-tcl-tools-test_cpu_speed-Fix-register-name.patch b/meta-oe/recipes-devtools/openocd/openocd/0092-tcl-tools-test_cpu_speed-Fix-register-name.patch new file mode 100644 index 000000000..5a89c3b39 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0092-tcl-tools-test_cpu_speed-Fix-register-name.patch @@ -0,0 +1,30 @@ +From 1528845331ad260bebda6b88b880baf725ffb3c3 Mon Sep 17 00:00:00 2001 +From: Marc Schink +Date: Thu, 9 Feb 2023 11:23:28 +0100 +Subject: [PATCH] tcl/tools/test_cpu_speed: Fix register name + +Use correct register name after it has beed changed +in commit 11ee500bffe4 ("target/armv7m: Rename xPSR to xpsr") + +Change-Id: I3648848f4b47af2d20d60c3e0ecef78f75f6d605 +Signed-off-by: Marc Schink +Reviewed-on: https://review.openocd.org/c/openocd/+/7473 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + tcl/tools/test_cpu_speed.tcl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tcl/tools/test_cpu_speed.tcl b/tcl/tools/test_cpu_speed.tcl +index cef2bbbd7..f1a3fb30e 100644 +--- a/tcl/tools/test_cpu_speed.tcl ++++ b/tcl/tools/test_cpu_speed.tcl +@@ -18,7 +18,7 @@ proc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } { + halt + + # Backup registers and memory. +- set backup_regs [get_reg -force {pc r0 xPSR}] ++ set backup_regs [get_reg -force {pc r0 xpsr}] + set backup_mem [read_memory $address 16 3] + + # We place the following code at the given address to measure the diff --git a/meta-oe/recipes-devtools/openocd/openocd/0093-tcl-remove-exec-permission-to-tcl-config-files.patch b/meta-oe/recipes-devtools/openocd/openocd/0093-tcl-remove-exec-permission-to-tcl-config-files.patch new file mode 100644 index 000000000..10a288d37 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0093-tcl-remove-exec-permission-to-tcl-config-files.patch @@ -0,0 +1,28 @@ +From b4e28446b8f2a116b088eef78744c8b529c1a747 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 6 Mar 2023 23:18:35 +0100 +Subject: [PATCH] tcl: remove exec permission to tcl config files + +With the new checkpatch we will not get this type of issues +anymore. +In mean time, let's fix what we have missed during the review +process. + +Change-Id: Iecebf9d43f51a29ee09505d360792793afd24b40 +Signed-off-by: Antonio Borneo +Fixes: 53556fcded05 ("tcl/interface: add Ashling Opella-LD FTDI config files") +Reviewed-on: https://review.openocd.org/c/openocd/+/7530 +Tested-by: jenkins +--- + tcl/interface/ftdi/ashling-opella-ld-jtag.cfg | 0 + tcl/interface/ftdi/ashling-opella-ld-swd.cfg | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) + mode change 100755 => 100644 tcl/interface/ftdi/ashling-opella-ld-jtag.cfg + mode change 100755 => 100644 tcl/interface/ftdi/ashling-opella-ld-swd.cfg + +diff --git a/tcl/interface/ftdi/ashling-opella-ld-jtag.cfg b/tcl/interface/ftdi/ashling-opella-ld-jtag.cfg +old mode 100755 +new mode 100644 +diff --git a/tcl/interface/ftdi/ashling-opella-ld-swd.cfg b/tcl/interface/ftdi/ashling-opella-ld-swd.cfg +old mode 100755 +new mode 100644 diff --git a/meta-oe/recipes-devtools/openocd/openocd/0094-svf-new-command-line-options-noreset-and-addcycles.patch b/meta-oe/recipes-devtools/openocd/openocd/0094-svf-new-command-line-options-noreset-and-addcycles.patch new file mode 100644 index 000000000..d71ec8630 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0094-svf-new-command-line-options-noreset-and-addcycles.patch @@ -0,0 +1,145 @@ +From b6b4f9d46a48aadc1de6bb5152ff4913661c9059 Mon Sep 17 00:00:00 2001 +From: Kai Schmitz +Date: Thu, 5 Jan 2023 13:50:53 +0100 +Subject: [PATCH] svf: new command line options -noreset and -addcycles + +-noreset: when using several SVF input files in a sequence it is not always + desireable to have a JTAG reset between the execution of the files. + The -noreset option skips this unwanted reset. + +-addcycles : some tests rely on a certain number of extra clock cycles + between the actual JTAG commands. The -addcycles option injects a number + x cycles after each SDR instruction. + +Signed-off-by: Kai Schmitz +Change-Id: I31932d6041dbc803be00016cd0a4f23fb2e7dbe1 +Reviewed-on: https://review.openocd.org/c/openocd/+/7433 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + doc/openocd.texi | 7 ++++++- + src/svf/svf.c | 29 +++++++++++++++++++++++++---- + 2 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index 414b4c405..0de101b6d 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -11433,7 +11433,8 @@ In a debug session using JTAG for its transport protocol, + OpenOCD supports running such test files. + + @deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{[-]quiet}] @ +- [@option{[-]nil}] [@option{[-]progress}] [@option{[-]ignore_error}] ++ [@option{[-]nil}] [@option{[-]progress}] [@option{[-]ignore_error}] @ ++ [@option{-noreset}] [@option{-addcycles @var{cyclecount}}] + This issues a JTAG reset (Test-Logic-Reset) and then + runs the SVF script from @file{filename}. + +@@ -11452,6 +11453,10 @@ on the real interface; + @item @option{[-]progress} enable progress indication; + @item @option{[-]ignore_error} continue execution despite TDO check + errors. ++@item @option{-noreset} omit JTAG reset (Test-Logic-Reset) before executing ++content of the SVF file; ++@item @option{-addcycles @var{cyclecount}} inject @var{cyclecount} number of ++additional TCLK cycles after each SDR scan instruction; + @end itemize + @end deffn + +diff --git a/src/svf/svf.c b/src/svf/svf.c +index a5374316e..719588067 100644 +--- a/src/svf/svf.c ++++ b/src/svf/svf.c +@@ -22,6 +22,7 @@ + #include "svf.h" + #include "helper/system.h" + #include ++#include + + /* SVF command */ + enum svf_command { +@@ -139,6 +140,9 @@ static const struct svf_statemove svf_statemoves[] = { + #define XXR_TDO (1 << 1) + #define XXR_MASK (1 << 2) + #define XXR_SMASK (1 << 3) ++ ++#define SVF_MAX_ADDCYCLES 255 ++ + struct svf_xxr_para { + int len; + int data_mask; +@@ -220,6 +224,8 @@ static int svf_buffer_index, svf_buffer_size; + static int svf_quiet; + static int svf_nil; + static int svf_ignore_error; ++static bool svf_noreset; ++static int svf_addcycles; + + /* Targeting particular tap */ + static int svf_tap_is_specified; +@@ -343,7 +349,7 @@ int svf_add_statemove(tap_state_t state_to) + COMMAND_HANDLER(handle_svf_command) + { + #define SVF_MIN_NUM_OF_OPTIONS 1 +-#define SVF_MAX_NUM_OF_OPTIONS 5 ++#define SVF_MAX_NUM_OF_OPTIONS 8 + int command_num = 0; + int ret = ERROR_OK; + int64_t time_measure_ms; +@@ -363,8 +369,18 @@ COMMAND_HANDLER(handle_svf_command) + svf_nil = 0; + svf_progress_enabled = 0; + svf_ignore_error = 0; ++ svf_noreset = false; ++ svf_addcycles = 0; ++ + for (unsigned int i = 0; i < CMD_ARGC; i++) { +- if (strcmp(CMD_ARGV[i], "-tap") == 0) { ++ if (strcmp(CMD_ARGV[i], "-addcycles") == 0) { ++ svf_addcycles = atoi(CMD_ARGV[i + 1]); ++ if (svf_addcycles > SVF_MAX_ADDCYCLES) { ++ command_print(CMD, "addcycles: %s out of range", CMD_ARGV[i + 1]); ++ return ERROR_FAIL; ++ } ++ i++; ++ } else if (strcmp(CMD_ARGV[i], "-tap") == 0) { + tap = jtag_tap_by_string(CMD_ARGV[i+1]); + if (!tap) { + command_print(CMD, "Tap: %s unknown", CMD_ARGV[i+1]); +@@ -382,6 +398,8 @@ COMMAND_HANDLER(handle_svf_command) + else if ((strcmp(CMD_ARGV[i], + "ignore_error") == 0) || (strcmp(CMD_ARGV[i], "-ignore_error") == 0)) + svf_ignore_error = 1; ++ else if (strcmp(CMD_ARGV[i], "-noreset") == 0) ++ svf_noreset = true; + else { + svf_fd = fopen(CMD_ARGV[i], "r"); + if (!svf_fd) { +@@ -424,7 +442,7 @@ COMMAND_HANDLER(handle_svf_command) + + memcpy(&svf_para, &svf_para_init, sizeof(svf_para)); + +- if (!svf_nil) { ++ if (!svf_nil && !svf_noreset) { + /* TAP_RESET */ + jtag_add_tlr(); + } +@@ -1189,6 +1207,9 @@ xxr_common: + svf_para.dr_end_state); + } + ++ if (svf_addcycles) ++ jtag_add_clocks(svf_addcycles); ++ + svf_buffer_index += (i + 7) >> 3; + } else if (command == SIR) { + /* check buffer size first, reallocate if necessary */ +@@ -1545,7 +1566,7 @@ static const struct command_registration svf_command_handlers[] = { + .handler = handle_svf_command, + .mode = COMMAND_EXEC, + .help = "Runs a SVF file.", +- .usage = "[-tap device.tap] [quiet] [nil] [progress] [ignore_error]", ++ .usage = "[-tap device.tap] [quiet] [nil] [progress] [ignore_error] [-noreset] [-addcycles numcycles]", + }, + COMMAND_REGISTRATION_DONE + }; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0095-helper-compiler-fix-build-on-MacOS.patch b/meta-oe/recipes-devtools/openocd/openocd/0095-helper-compiler-fix-build-on-MacOS.patch new file mode 100644 index 000000000..b9a30be06 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0095-helper-compiler-fix-build-on-MacOS.patch @@ -0,0 +1,41 @@ +From 9ce6b0898e5c0b2d6b6928b93b18137fecd6a32d Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 19 Mar 2023 10:57:04 +0100 +Subject: [PATCH] helper/compiler: fix build on MacOS + +On MacOS, clang defines [1]: + #define __nonnull _Nonnull +that creates incompatibility with GCC and with the macro __nonnull +defined in some libc. + +Detect clang on MacOS and undefine __nonnull. + +Change-Id: I64fcf51b102ea91c196e657debd8c267943a2b08 +Signed-off-by: Antonio Borneo +Links: [1] https://github.com/llvm/llvm-project/blob/llvmorg-16.0.0/clang/lib/Frontend/InitPreprocessor.cpp#L1226 +Reviewed-on: https://review.openocd.org/c/openocd/+/7544 +Tested-by: jenkins +--- + src/helper/compiler.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/helper/compiler.h b/src/helper/compiler.h +index 8f6c09950..33a075d64 100644 +--- a/src/helper/compiler.h ++++ b/src/helper/compiler.h +@@ -32,7 +32,15 @@ + /* + * The __nonnull function attribute marks pointer parameters that + * must not be NULL. ++ * ++ * clang for Apple defines ++ * #define __nonnull _Nonnull ++ * that is a per argument attribute, incompatible with the gcc per function attribute __nonnull__. ++ * Undefine it to keep compatibility among compilers. + */ ++#if defined(__clang__) && defined(__APPLE__) ++# undef __nonnull ++#endif + #ifndef __nonnull + # if __has_attribute(__nonnull__) + # define __nonnull(params) __attribute__ ((__nonnull__ params)) diff --git a/meta-oe/recipes-devtools/openocd/openocd/0096-rtos-nuttx-add-Espressif-target-support-and-refactor.patch b/meta-oe/recipes-devtools/openocd/openocd/0096-rtos-nuttx-add-Espressif-target-support-and-refactor.patch new file mode 100644 index 000000000..ea8e730ec --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0096-rtos-nuttx-add-Espressif-target-support-and-refactor.patch @@ -0,0 +1,758 @@ +From ee31f1578a333a75737bc5b183cd4ae98cdaf798 Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Sun, 22 Jan 2023 23:43:03 +0100 +Subject: [PATCH] rtos/nuttx: add Espressif target support and refactoring + +Almost written from the beginning in a modern OpenOCD way. +- Endiannes support +- Proper variable types +- Align with the other rtos implementations + +Signed-off-by: Erhan Kurubas +Change-Id: I0868a22da2ed2ab664c82b17c171dc59ede78d10 +Reviewed-on: https://review.openocd.org/c/openocd/+/7444 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/rtos/Makefile.am | 3 +- + src/rtos/nuttx.c | 541 +++++++++++++++++++------------- + src/rtos/nuttx_header.h | 60 ---- + src/rtos/rtos_nuttx_stackings.h | 3 + + 4 files changed, 329 insertions(+), 278 deletions(-) + delete mode 100644 src/rtos/nuttx_header.h + +diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am +index b0f7daf5f..0796910de 100644 +--- a/src/rtos/Makefile.am ++++ b/src/rtos/Makefile.am +@@ -34,5 +34,4 @@ noinst_LTLIBRARIES += %D%/librtos.la + %D%/rtos_mqx_stackings.h \ + %D%/rtos_riot_stackings.h \ + %D%/rtos_ucos_iii_stackings.h \ +- %D%/rtos_nuttx_stackings.h \ +- %D%/nuttx_header.h ++ %D%/rtos_nuttx_stackings.h +diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c +index 78271181e..0616af0f4 100644 +--- a/src/rtos/nuttx.c ++++ b/src/rtos/nuttx.c +@@ -18,53 +18,60 @@ + #include "rtos.h" + #include "helper/log.h" + #include "helper/types.h" +-#include "server/gdb_server.h" +- +-#include "nuttx_header.h" ++#include "target/register.h" + #include "rtos_nuttx_stackings.h" + +-int rtos_thread_packet(struct connection *connection, const char *packet, int packet_size); +- +-#ifdef CONFIG_DISABLE_SIGNALS +-#define SIG_QUEUE_NUM 0 +-#else +-#define SIG_QUEUE_NUM 1 +-#endif /* CONFIG_DISABLE_SIGNALS */ +- +-#ifdef CONFIG_DISABLE_MQUEUE +-#define M_QUEUE_NUM 0 +-#else +-#define M_QUEUE_NUM 2 +-#endif /* CONFIG_DISABLE_MQUEUE */ +- +-#ifdef CONFIG_PAGING +-#define PAGING_QUEUE_NUM 1 +-#else +-#define PAGING_QUEUE_NUM 0 +-#endif /* CONFIG_PAGING */ ++#define NAME_SIZE 32 ++#define EXTRAINFO_SIZE 256 + ++/* Only 32-bit CPUs are supported by the current implementation. Supporting ++ * other CPUs will require reading this information from the target and ++ * adapting the code accordingly. ++ */ ++#define PTR_WIDTH 4 + +-#define TASK_QUEUE_NUM (6 + SIG_QUEUE_NUM + M_QUEUE_NUM + PAGING_QUEUE_NUM) ++struct nuttx_params { ++ const char *target_name; ++ const struct rtos_register_stacking *stacking; ++ const struct rtos_register_stacking *(*select_stackinfo)(struct target *target); ++}; + ++/* ++ * struct tcbinfo_s is located in the sched.h ++ * https://github.com/apache/nuttx/blob/master/include/nuttx/sched.h ++ */ ++#define TCBINFO_TARGET_SIZE 22 ++struct tcbinfo { ++ uint16_t pid_off; /* Offset of tcb.pid */ ++ uint16_t state_off; /* Offset of tcb.task_state */ ++ uint16_t pri_off; /* Offset of tcb.sched_priority */ ++ uint16_t name_off; /* Offset of tcb.name */ ++ uint16_t regs_off; /* Offset of tcb.regs */ ++ uint16_t basic_num; /* Num of genernal regs */ ++ uint16_t total_num; /* Num of regs in tcbinfo.reg_offs */ ++ target_addr_t xcpreg_off; /* Offset pointer of xcp.regs */ ++}; + +-/* see nuttx/sched/os_start.c */ +-static char *nuttx_symbol_list[] = { +- "g_readytorun", /* 0: must be top of this array */ +- "g_tasklisttable", +- NULL ++struct symbols { ++ const char *name; ++ bool optional; + }; + +-/* see nuttx/include/nuttx/sched.h */ +-struct tcb { +- uint32_t flink; +- uint32_t blink; +- uint8_t dat[512]; ++/* Used to index the list of retrieved symbols. See nuttx_symbol_list for the order. */ ++enum nuttx_symbol_vals { ++ NX_SYM_READYTORUN = 0, ++ NX_SYM_PIDHASH, ++ NX_SYM_NPIDHASH, ++ NX_SYM_TCB_INFO, + }; + +-static struct { +- uint32_t addr; +- uint32_t prio; +-} g_tasklist[TASK_QUEUE_NUM]; ++static const struct symbols nuttx_symbol_list[] = { ++ { "g_readytorun", false }, ++ { "g_pidhash", false }, ++ { "g_npidhash", false }, ++ { "g_tcbinfo", false }, ++ { NULL, false } ++}; + + static char *task_state_str[] = { + "INVALID", +@@ -73,261 +80,363 @@ static char *task_state_str[] = { + "RUNNING", + "INACTIVE", + "WAIT_SEM", +-#ifndef CONFIG_DISABLE_SIGNALS + "WAIT_SIG", +-#endif /* CONFIG_DISABLE_SIGNALS */ +-#ifndef CONFIG_DISABLE_MQUEUE + "WAIT_MQNOTEMPTY", + "WAIT_MQNOTFULL", +-#endif /* CONFIG_DISABLE_MQUEUE */ +-#ifdef CONFIG_PAGING + "WAIT_PAGEFILL", +-#endif /* CONFIG_PAGING */ ++ "STOPPED", + }; + +-static int pid_offset = PID; +-static int state_offset = STATE; +-static int name_offset = NAME; +-static int xcpreg_offset = XCPREG; +-static int name_size = NAME_SIZE; ++static const struct rtos_register_stacking *cortexm_select_stackinfo(struct target *target); ++ ++static const struct nuttx_params nuttx_params_list[] = { ++ { ++ .target_name = "cortex_m", ++ .stacking = NULL, ++ .select_stackinfo = cortexm_select_stackinfo, ++ }, ++ { ++ .target_name = "hla_target", ++ .stacking = NULL, ++ .select_stackinfo = cortexm_select_stackinfo, ++ }, ++ { ++ .target_name = "esp32", ++ .stacking = &nuttx_esp32_stacking, ++ }, ++ { ++ .target_name = "esp32s2", ++ .stacking = &nuttx_esp32s2_stacking, ++ }, ++ { ++ .target_name = "esp32s3", ++ .stacking = &nuttx_esp32s3_stacking, ++ }, ++ { ++ .target_name = "esp32c3", ++ .stacking = &nuttx_riscv_stacking, ++ }, ++}; + +-static int rcmd_offset(const char *cmd, const char *name) ++static bool cortexm_hasfpu(struct target *target) + { +- if (strncmp(cmd, name, strlen(name))) +- return -1; ++ uint32_t cpacr; ++ struct armv7m_common *armv7m_target = target_to_armv7m(target); + +- if (strlen(cmd) <= strlen(name) + 1) +- return -1; ++ if (!is_armv7m(armv7m_target) || armv7m_target->fp_feature == FP_NONE) ++ return false; + +- return atoi(cmd + strlen(name)); ++ int retval = target_read_u32(target, FPU_CPACR, &cpacr); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read CPACR register to check FPU state"); ++ return false; ++ } ++ ++ return cpacr & 0x00F00000; + } + +-static int nuttx_thread_packet(struct connection *connection, +- char const *packet, int packet_size) ++static const struct rtos_register_stacking *cortexm_select_stackinfo(struct target *target) + { +- char cmd[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for null-termination */ +- +- if (!strncmp(packet, "qRcmd", 5)) { +- size_t len = unhexify((uint8_t *)cmd, packet + 6, sizeof(cmd)); +- int offset; +- +- if (len <= 0) +- goto pass; +- +- offset = rcmd_offset(cmd, "nuttx.pid_offset"); +- +- if (offset >= 0) { +- LOG_INFO("pid_offset: %d", offset); +- pid_offset = offset; +- goto retok; +- } +- +- offset = rcmd_offset(cmd, "nuttx.state_offset"); ++ return cortexm_hasfpu(target) ? &nuttx_stacking_cortex_m_fpu : &nuttx_stacking_cortex_m; ++} + +- if (offset >= 0) { +- LOG_INFO("state_offset: %d", offset); +- state_offset = offset; +- goto retok; +- } ++static bool nuttx_detect_rtos(struct target *target) ++{ ++ if (target->rtos->symbols && ++ target->rtos->symbols[NX_SYM_READYTORUN].address != 0 && ++ target->rtos->symbols[NX_SYM_PIDHASH].address != 0) ++ return true; ++ return false; ++} + +- offset = rcmd_offset(cmd, "nuttx.name_offset"); ++static int nuttx_create(struct target *target) ++{ ++ const struct nuttx_params *param; ++ unsigned int i; + +- if (offset >= 0) { +- LOG_INFO("name_offset: %d", offset); +- name_offset = offset; +- goto retok; ++ for (i = 0; i < ARRAY_SIZE(nuttx_params_list); i++) { ++ param = &nuttx_params_list[i]; ++ if (strcmp(target_type_name(target), param->target_name) == 0) { ++ LOG_INFO("Detected target \"%s\"", param->target_name); ++ break; + } ++ } + +- offset = rcmd_offset(cmd, "nuttx.xcpreg_offset"); +- +- if (offset >= 0) { +- LOG_INFO("xcpreg_offset: %d", offset); +- xcpreg_offset = offset; +- goto retok; +- } ++ if (i >= ARRAY_SIZE(nuttx_params_list)) { ++ LOG_ERROR("Could not find \"%s\" target in NuttX compatibility list", target_type_name(target)); ++ return JIM_ERR; ++ } + +- offset = rcmd_offset(cmd, "nuttx.name_size"); ++ /* We found a target in our list, copy its reference. */ ++ target->rtos->rtos_specific_params = (void *)param; + +- if (offset >= 0) { +- LOG_INFO("name_size: %d", offset); +- name_size = offset; +- goto retok; +- } +- } +-pass: +- return rtos_thread_packet(connection, packet, packet_size); +-retok: +- gdb_put_packet(connection, "OK", 2); +- return ERROR_OK; ++ return JIM_OK; + } + +- +-static bool nuttx_detect_rtos(struct target *target) ++static int nuttx_smp_init(struct target *target) + { +- if ((target->rtos->symbols) && +- (target->rtos->symbols[0].address != 0) && +- (target->rtos->symbols[1].address != 0)) { +- return true; +- } +- return false; ++ /* Return OK for now so that the initialisation sequence doesn't stop. ++ * SMP case will be implemented later. */ ++ return ERROR_OK; + } + +-static int nuttx_create(struct target *target) ++static target_addr_t target_buffer_get_addr(struct target *target, const uint8_t *buffer) + { +- +- target->rtos->gdb_thread_packet = nuttx_thread_packet; +- LOG_INFO("target type name = %s", target->type->name); +- return 0; ++#if PTR_WIDTH == 8 ++ return target_buffer_get_u64(target, buffer); ++#else ++ return target_buffer_get_u32(target, buffer); ++#endif + } + + static int nuttx_update_threads(struct rtos *rtos) + { +- uint32_t thread_count; +- struct tcb tcb; +- int ret; +- uint32_t head; +- uint32_t tcb_addr; +- uint32_t i; ++ struct tcbinfo tcbinfo; ++ uint32_t pidhashaddr, npidhash, tcbaddr; ++ uint16_t pid; + uint8_t state; + + if (!rtos->symbols) { +- LOG_ERROR("No symbols for NuttX"); +- return -3; ++ LOG_ERROR("No symbols for nuttx"); ++ return ERROR_FAIL; + } + +- /* free previous thread details */ ++ /* Free previous thread details */ + rtos_free_threadlist(rtos); + +- ret = target_read_buffer(rtos->target, rtos->symbols[1].address, +- sizeof(g_tasklist), (uint8_t *)&g_tasklist); +- if (ret) { +- LOG_ERROR("target_read_buffer : ret = %d\n", ret); ++ /* NuttX provides a hash table that keeps track of all the TCBs. ++ * We first read its size from g_npidhash and its address from g_pidhash. ++ * Its content is then read from these values. ++ */ ++ int ret = target_read_u32(rtos->target, rtos->symbols[NX_SYM_NPIDHASH].address, &npidhash); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read g_npidhash: ret = %d", ret); + return ERROR_FAIL; + } + +- thread_count = 0; ++ LOG_DEBUG("Hash table size (g_npidhash) = %" PRId32, npidhash); ++ ++ ret = target_read_u32(rtos->target, rtos->symbols[NX_SYM_PIDHASH].address, &pidhashaddr); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read g_pidhash address: ret = %d", ret); ++ return ERROR_FAIL; ++ } + +- for (i = 0; i < TASK_QUEUE_NUM; i++) { ++ LOG_DEBUG("Hash table address (g_pidhash) = %" PRIx32, pidhashaddr); ++ ++ uint8_t *pidhash = malloc(npidhash * PTR_WIDTH); ++ if (!pidhash) { ++ LOG_ERROR("Failed to allocate pidhash"); ++ return ERROR_FAIL; ++ } + +- if (g_tasklist[i].addr == 0) ++ ret = target_read_buffer(rtos->target, pidhashaddr, PTR_WIDTH * npidhash, pidhash); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read tcbhash: ret = %d", ret); ++ goto errout; ++ } ++ ++ /* NuttX provides a struct that contains TCB offsets for required members. ++ * Read its content from g_tcbinfo. ++ */ ++ uint8_t buff[TCBINFO_TARGET_SIZE]; ++ ret = target_read_buffer(rtos->target, rtos->symbols[NX_SYM_TCB_INFO].address, sizeof(buff), buff); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read tcbinfo: ret = %d", ret); ++ goto errout; ++ } ++ tcbinfo.pid_off = target_buffer_get_u16(rtos->target, buff); ++ tcbinfo.state_off = target_buffer_get_u16(rtos->target, buff + 2); ++ tcbinfo.pri_off = target_buffer_get_u16(rtos->target, buff + 4); ++ tcbinfo.name_off = target_buffer_get_u16(rtos->target, buff + 6); ++ tcbinfo.regs_off = target_buffer_get_u16(rtos->target, buff + 8); ++ tcbinfo.basic_num = target_buffer_get_u16(rtos->target, buff + 10); ++ tcbinfo.total_num = target_buffer_get_u16(rtos->target, buff + 12); ++ tcbinfo.xcpreg_off = target_buffer_get_addr(rtos->target, buff + 14); ++ ++ /* The head of the g_readytorun list is the currently running task. ++ * Reading in a temporary variable first to avoid endianness issues, ++ * rtos->current_thread is int64_t. */ ++ uint32_t current_thread; ++ ret = target_read_u32(rtos->target, rtos->symbols[NX_SYM_READYTORUN].address, ¤t_thread); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read g_readytorun: ret = %d", ret); ++ goto errout; ++ } ++ rtos->current_thread = current_thread; ++ ++ uint32_t thread_count = 0; ++ ++ for (unsigned int i = 0; i < npidhash; i++) { ++ tcbaddr = target_buffer_get_u32(rtos->target, &pidhash[i * PTR_WIDTH]); ++ ++ if (!tcbaddr) + continue; + +- ret = target_read_u32(rtos->target, g_tasklist[i].addr, +- &head); ++ ret = target_read_u16(rtos->target, tcbaddr + tcbinfo.pid_off, &pid); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read PID of TCB@0x%x from pidhash[%d]: ret = %d", ++ tcbaddr, i, ret); ++ goto errout; ++ } + +- if (ret) { +- LOG_ERROR("target_read_u32 : ret = %d\n", ret); +- return ERROR_FAIL; ++ ret = target_read_u8(rtos->target, tcbaddr + tcbinfo.state_off, &state); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read state of TCB@0x%x from pidhash[%d]: ret = %d", ++ tcbaddr, i, ret); ++ goto errout; + } + +- /* readytorun head is current thread */ +- if (g_tasklist[i].addr == rtos->symbols[0].address) +- rtos->current_thread = head; ++ struct thread_detail *new_thread_details = realloc(rtos->thread_details, ++ sizeof(struct thread_detail) * (thread_count + 1)); ++ if (!new_thread_details) { ++ ret = ERROR_FAIL; ++ goto errout; ++ } + ++ struct thread_detail *thread = &new_thread_details[thread_count]; ++ thread->threadid = tcbaddr; ++ thread->exists = true; ++ thread->extra_info_str = NULL; + +- tcb_addr = head; +- while (tcb_addr) { +- struct thread_detail *thread; +- ret = target_read_buffer(rtos->target, tcb_addr, +- sizeof(tcb), (uint8_t *)&tcb); +- if (ret) { +- LOG_ERROR("target_read_buffer : ret = %d\n", +- ret); +- return ERROR_FAIL; +- } +- thread_count++; +- +- rtos->thread_details = realloc(rtos->thread_details, +- sizeof(struct thread_detail) * thread_count); +- thread = &rtos->thread_details[thread_count - 1]; +- thread->threadid = tcb_addr; +- thread->exists = true; +- +- state = tcb.dat[state_offset - 8]; +- thread->extra_info_str = NULL; +- if (state < ARRAY_SIZE(task_state_str)) { +- thread->extra_info_str = malloc(256); +- snprintf(thread->extra_info_str, 256, "pid:%d, %s", +- tcb.dat[pid_offset - 8] | +- tcb.dat[pid_offset - 8 + 1] << 8, +- task_state_str[state]); +- } ++ rtos->thread_details = new_thread_details; ++ thread_count++; + +- if (name_offset) { +- thread->thread_name_str = malloc(name_size + 1); +- snprintf(thread->thread_name_str, name_size, +- "%s", (char *)&tcb.dat[name_offset - 8]); +- } else { +- thread->thread_name_str = malloc(sizeof("None")); +- strcpy(thread->thread_name_str, "None"); ++ if (state < ARRAY_SIZE(task_state_str)) { ++ thread->extra_info_str = malloc(EXTRAINFO_SIZE); ++ if (!thread->extra_info_str) { ++ ret = ERROR_FAIL; ++ goto errout; + } ++ snprintf(thread->extra_info_str, EXTRAINFO_SIZE, "pid:%d, %s", ++ pid, ++ task_state_str[state]); ++ } + +- tcb_addr = tcb.flink; ++ if (tcbinfo.name_off) { ++ thread->thread_name_str = calloc(NAME_SIZE + 1, sizeof(char)); ++ if (!thread->thread_name_str) { ++ ret = ERROR_FAIL; ++ goto errout; ++ } ++ ret = target_read_buffer(rtos->target, tcbaddr + tcbinfo.name_off, ++ sizeof(char) * NAME_SIZE, (uint8_t *)thread->thread_name_str); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read thread's name: ret = %d", ret); ++ goto errout; ++ } ++ } else { ++ thread->thread_name_str = strdup("None"); + } + } +- rtos->thread_count = thread_count; + +- return 0; ++ ret = ERROR_OK; ++ rtos->thread_count = thread_count; ++errout: ++ free(pidhash); ++ return ret; + } + +- +-/* +- * thread_id = tcb address; +- */ +-static int nuttx_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, ++static int nuttx_getreg_current_thread(struct rtos *rtos, + struct rtos_reg **reg_list, int *num_regs) + { +- int retval; +- +- /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4F */ +- bool cm4_fpu_enabled = false; +- struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target); +- if (is_armv7m(armv7m_target)) { +- if (armv7m_target->fp_feature == FPV4_SP) { +- /* Found ARM v7m target which includes a FPU */ +- uint32_t cpacr; +- +- retval = target_read_u32(rtos->target, FPU_CPACR, &cpacr); +- if (retval != ERROR_OK) { +- LOG_ERROR("Could not read CPACR register to check FPU state"); +- return -1; +- } ++ struct reg **gdb_reg_list; ++ ++ /* Registers for currently running thread are not on task's stack and ++ * should be retrieved from reg caches via target_get_gdb_reg_list */ ++ int ret = target_get_gdb_reg_list(rtos->target, &gdb_reg_list, num_regs, ++ REG_CLASS_GENERAL); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("target_get_gdb_reg_list failed %d", ret); ++ return ret; ++ } + +- /* Check if CP10 and CP11 are set to full access. */ +- if (cpacr & 0x00F00000) { +- /* Found target with enabled FPU */ +- cm4_fpu_enabled = 1; +- } ++ *reg_list = calloc(*num_regs, sizeof(struct rtos_reg)); ++ if (!(*reg_list)) { ++ LOG_ERROR("Failed to alloc memory for %d", *num_regs); ++ free(gdb_reg_list); ++ return ERROR_FAIL; ++ } ++ ++ for (int i = 0; i < *num_regs; i++) { ++ (*reg_list)[i].number = gdb_reg_list[i]->number; ++ (*reg_list)[i].size = gdb_reg_list[i]->size; ++ memcpy((*reg_list)[i].value, gdb_reg_list[i]->value, ((*reg_list)[i].size + 7) / 8); ++ } ++ ++ free(gdb_reg_list); ++ ++ return ERROR_OK; ++} ++ ++static int nuttx_getregs_fromstack(struct rtos *rtos, int64_t thread_id, ++ struct rtos_reg **reg_list, int *num_regs) ++{ ++ uint16_t xcpreg_off; ++ uint32_t regsaddr; ++ const struct nuttx_params *priv = rtos->rtos_specific_params; ++ const struct rtos_register_stacking *stacking = priv->stacking; ++ ++ if (!stacking) { ++ if (priv->select_stackinfo) { ++ stacking = priv->select_stackinfo(rtos->target); ++ } else { ++ LOG_ERROR("Can't find a way to get stacking info"); ++ return ERROR_FAIL; + } + } + +- const struct rtos_register_stacking *stacking; +- if (cm4_fpu_enabled) +- stacking = &nuttx_stacking_cortex_m_fpu; +- else +- stacking = &nuttx_stacking_cortex_m; ++ int ret = target_read_u16(rtos->target, ++ rtos->symbols[NX_SYM_TCB_INFO].address + offsetof(struct tcbinfo, regs_off), ++ &xcpreg_off); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read registers' offset: ret = %d", ret); ++ return ERROR_FAIL; ++ } ++ ++ ret = target_read_u32(rtos->target, thread_id + xcpreg_off, ®saddr); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("Failed to read registers' address: ret = %d", ret); ++ return ERROR_FAIL; ++ } + +- return rtos_generic_stack_read(rtos->target, stacking, +- (uint32_t)thread_id + xcpreg_offset, reg_list, num_regs); ++ return rtos_generic_stack_read(rtos->target, stacking, regsaddr, reg_list, num_regs); + } + +-static int nuttx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]) ++static int nuttx_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, ++ struct rtos_reg **reg_list, int *num_regs) + { +- unsigned int i; ++ if (!rtos) { ++ LOG_ERROR("NUTTX: out of memory"); ++ return ERROR_FAIL; ++ } ++ ++ if (thread_id == rtos->current_thread) ++ return nuttx_getreg_current_thread(rtos, reg_list, num_regs); ++ return nuttx_getregs_fromstack(rtos, thread_id, reg_list, num_regs); ++} + +- *symbol_list = (struct symbol_table_elem *) calloc(1, +- sizeof(struct symbol_table_elem) * ARRAY_SIZE(nuttx_symbol_list)); ++static int nuttx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]) ++{ ++ *symbol_list = calloc(ARRAY_SIZE(nuttx_symbol_list), sizeof(**symbol_list)); ++ if (!*symbol_list) { ++ LOG_ERROR("NUTTX: out of memory"); ++ return ERROR_FAIL; ++ } + +- for (i = 0; i < ARRAY_SIZE(nuttx_symbol_list); i++) +- (*symbol_list)[i].symbol_name = nuttx_symbol_list[i]; ++ for (unsigned int i = 0; i < ARRAY_SIZE(nuttx_symbol_list); i++) { ++ (*symbol_list)[i].symbol_name = nuttx_symbol_list[i].name; ++ (*symbol_list)[i].optional = nuttx_symbol_list[i].optional; ++ } + +- return 0; ++ return ERROR_OK; + } + + const struct rtos_type nuttx_rtos = { + .name = "nuttx", + .detect_rtos = nuttx_detect_rtos, + .create = nuttx_create, ++ .smp_init = nuttx_smp_init, + .update_threads = nuttx_update_threads, + .get_thread_reg_list = nuttx_get_thread_reg_list, + .get_symbol_list_to_lookup = nuttx_get_symbol_list_to_lookup, +diff --git a/src/rtos/nuttx_header.h b/src/rtos/nuttx_header.h +deleted file mode 100644 +index 3436df1eb..000000000 +--- a/src/rtos/nuttx_header.h ++++ /dev/null +@@ -1,60 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-or-later */ +- +-/*************************************************************************** +- * Copyright 2016,2017 Sony Video & Sound Products Inc. * +- * Masatoshi Tateishi - Masatoshi.Tateishi@jp.sony.com * +- * Masayuki Ishikawa - Masayuki.Ishikawa@jp.sony.com * +- ***************************************************************************/ +- +-#ifndef OPENOCD_RTOS_NUTTX_HEADER_H +-#define OPENOCD_RTOS_NUTTX_HEADER_H +- +-/* gdb script to update the header file +- according to kernel version and build option +- before executing function awareness +- kernel symbol must be loaded : symbol nuttx +- +-define awareness +- set logging off +- set logging file nuttx_header.h +- set logging on +- +- printf "#define PID %p\n",&((struct tcb_s *)(0))->pid +- printf "#define XCPREG %p\n",&((struct tcb_s *)(0))->xcp.regs +- printf "#define STATE %p\n",&((struct tcb_s *)(0))->task_state +- printf "#define NAME %p\n",&((struct tcb_s *)(0))->name +- printf "#define NAME_SIZE %d\n",sizeof(((struct tcb_s *)(0))->name) +- end +- +- +- OR ~/.gdbinit +- +- +-define hookpost-file +- +- if &g_readytorun != 0 +- eval "monitor nuttx.pid_offset %d", &((struct tcb_s *)(0))->pid +- eval "monitor nuttx.xcpreg_offset %d", &((struct tcb_s *)(0))->xcp.regs +- eval "monitor nuttx.state_offset %d", &((struct tcb_s *)(0))->task_state +- eval "monitor nuttx.name_offset %d", &((struct tcb_s *)(0))->name +- eval "monitor nuttx.name_size %d", sizeof(((struct tcb_s *)(0))->name) +- end +- +-end +- +-*/ +- +-/* default offset */ +-#define PID 0xc +-#define XCPREG 0x70 +-#define STATE 0x19 +-#define NAME 0xb8 +-#define NAME_SIZE 32 +- +-/* defconfig of nuttx */ +-/* #define CONFIG_DISABLE_SIGNALS */ +-#define CONFIG_DISABLE_MQUEUE +-/* #define CONFIG_PAGING */ +- +- +-#endif /* OPENOCD_RTOS_NUTTX_HEADER_H */ +diff --git a/src/rtos/rtos_nuttx_stackings.h b/src/rtos/rtos_nuttx_stackings.h +index 2e5f09212..213a06033 100644 +--- a/src/rtos/rtos_nuttx_stackings.h ++++ b/src/rtos/rtos_nuttx_stackings.h +@@ -8,5 +8,8 @@ + extern const struct rtos_register_stacking nuttx_stacking_cortex_m; + extern const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu; + extern const struct rtos_register_stacking nuttx_riscv_stacking; ++extern const struct rtos_register_stacking nuttx_esp32_stacking; ++extern const struct rtos_register_stacking nuttx_esp32s2_stacking; ++extern const struct rtos_register_stacking nuttx_esp32s3_stacking; + + #endif /* INCLUDED_RTOS_NUTTX_STACKINGS_H */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0097-target-espressif-check-common_magic-instead-of-gdb_a.patch b/meta-oe/recipes-devtools/openocd/openocd/0097-target-espressif-check-common_magic-instead-of-gdb_a.patch new file mode 100644 index 000000000..aac158c5b --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0097-target-espressif-check-common_magic-instead-of-gdb_a.patch @@ -0,0 +1,42 @@ +From faeae51d7f497d83ab166329abb1f06aa5903774 Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Wed, 15 Mar 2023 01:22:10 +0300 +Subject: [PATCH] target/espressif: check common_magic instead of gdb_arch + string + +The value returned by target_get_gdb_arch() is something specific for GDB. +There could be several variants of the same CPU. +If we start implementing all the variants, checking the string value, +could become incorrect. +It's better to check for xtensa->common_magic == XTENSA_COMMON_MAGIC + +Signed-off-by: Erhan Kurubas +Change-Id: I20f3fdced176c3b9ab00f889743161ecad7280f9 +Reviewed-on: https://review.openocd.org/c/openocd/+/7536 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/target/espressif/esp_semihosting.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/target/espressif/esp_semihosting.c b/src/target/espressif/esp_semihosting.c +index 5e9cb9457..51d499866 100644 +--- a/src/target/espressif/esp_semihosting.c ++++ b/src/target/espressif/esp_semihosting.c +@@ -17,12 +17,10 @@ + + static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target) + { +- const char *arch = target_get_gdb_arch(target); +- if (arch) { +- if (strncmp(arch, "xtensa", 6) == 0) +- return &target_to_esp_xtensa(target)->semihost; +- /* TODO: add riscv */ +- } ++ struct xtensa *xtensa = target->arch_info; ++ if (xtensa->common_magic == XTENSA_COMMON_MAGIC) ++ return &target_to_esp_xtensa(target)->semihost; ++ /* TODO: add riscv */ + LOG_ERROR("Unknown target arch!"); + return NULL; + } diff --git a/meta-oe/recipes-devtools/openocd/openocd/0098-target-adi_v5_swd-update-comment-about-SWD-capabilit.patch b/meta-oe/recipes-devtools/openocd/openocd/0098-target-adi_v5_swd-update-comment-about-SWD-capabilit.patch new file mode 100644 index 000000000..9c03a2aaa --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0098-target-adi_v5_swd-update-comment-about-SWD-capabilit.patch @@ -0,0 +1,29 @@ +From 6ecd99ff9b98778d5655d6b6fc245dd8f344d365 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Tue, 14 Mar 2023 19:43:21 +0100 +Subject: [PATCH] target/adi_v5_swd: update comment about SWD capability + +The multidrop SWD is also supported. + +Change-Id: I9fefc54fc9d40a75194285cd6e0f10c5c347d9b6 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7537 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/target/adi_v5_swd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c +index aea730d4d..653f91f13 100644 +--- a/src/target/adi_v5_swd.c ++++ b/src/target/adi_v5_swd.c +@@ -13,7 +13,7 @@ + * is a transport level interface, with "target/arm_adi_v5.[hc]" code + * understanding operation semantics, shared with the JTAG transport. + * +- * Single-DAP support only. ++ * Single DAP and multidrop-SWD support. + * + * for details, see "ARM IHI 0031A" + * ARM Debug Interface v5 Architecture Specification diff --git a/meta-oe/recipes-devtools/openocd/openocd/0099-target-adi_v5_jtag-fix-endianness-error-in-transacti.patch b/meta-oe/recipes-devtools/openocd/openocd/0099-target-adi_v5_jtag-fix-endianness-error-in-transacti.patch new file mode 100644 index 000000000..ad150aca4 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0099-target-adi_v5_jtag-fix-endianness-error-in-transacti.patch @@ -0,0 +1,46 @@ +From 415715d91a11ea4ed6db3a1fd760741a22b6e098 Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Tue, 14 Mar 2023 15:11:14 +0100 +Subject: [PATCH] target/adi_v5_jtag: fix endianness error in transaction + replay + +The code for JTAG WAIT recovery did not handle DP_SELECT +endianness. + +While on it, mark missing ADIv6 DP SELECT1 handling as TODO. + +Change-Id: I44f3bc8fc9fd2483c0293b6d4f2c51a60ca01873 +Signed-off-by: Tomas Vanek +Reviewed-on: https://review.openocd.org/c/openocd/+/7540 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/target/adi_v5_jtag.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c +index eeb796be4..9f66adc68 100644 +--- a/src/target/adi_v5_jtag.c ++++ b/src/target/adi_v5_jtag.c +@@ -566,14 +566,20 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) + /* restore SELECT register first */ + if (!list_empty(&replay_list)) { + el = list_first_entry(&replay_list, struct dap_cmd, lh); ++ ++ uint8_t out_value_buf[4]; ++ buf_set_u32(out_value_buf, 0, 32, (uint32_t)(el->dp_select)); ++ + tmp = dap_cmd_new(dap, JTAG_DP_DPACC, +- DP_SELECT, DPAP_WRITE, (uint8_t *)&el->dp_select, NULL, 0); ++ DP_SELECT, DPAP_WRITE, out_value_buf, NULL, 0); + if (!tmp) { + retval = ERROR_JTAG_DEVICE_ERROR; + goto done; + } + list_add(&tmp->lh, &replay_list); + ++ /* TODO: ADIv6 DP SELECT1 handling */ ++ + dap->select = DP_SELECT_INVALID; + } + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0100-svf-fix-leaking-file-descriptor.patch b/meta-oe/recipes-devtools/openocd/openocd/0100-svf-fix-leaking-file-descriptor.patch new file mode 100644 index 000000000..67283b70e --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0100-svf-fix-leaking-file-descriptor.patch @@ -0,0 +1,54 @@ +From 86827a961a22815ebd5fa367468ca7444f0ee2e1 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Fri, 10 Mar 2023 11:50:08 +0100 +Subject: [PATCH] svf: fix leaking file descriptor + +The file descriptor svf_fd is not closed on command error, thus +leaking memory. + +Close svf_fd on errors. +While there, properly initialize svf_fd using NULL instead of 0. + +Change-Id: I5efe9ce576a3a50588b30000222665e26161dfdc +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7532 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +Reviewed-by: +--- + src/svf/svf.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/svf/svf.c b/src/svf/svf.c +index 719588067..05fb21d63 100644 +--- a/src/svf/svf.c ++++ b/src/svf/svf.c +@@ -377,6 +377,9 @@ COMMAND_HANDLER(handle_svf_command) + svf_addcycles = atoi(CMD_ARGV[i + 1]); + if (svf_addcycles > SVF_MAX_ADDCYCLES) { + command_print(CMD, "addcycles: %s out of range", CMD_ARGV[i + 1]); ++ if (svf_fd) ++ fclose(svf_fd); ++ svf_fd = NULL; + return ERROR_FAIL; + } + i++; +@@ -384,6 +387,9 @@ COMMAND_HANDLER(handle_svf_command) + tap = jtag_tap_by_string(CMD_ARGV[i+1]); + if (!tap) { + command_print(CMD, "Tap: %s unknown", CMD_ARGV[i+1]); ++ if (svf_fd) ++ fclose(svf_fd); ++ svf_fd = NULL; + return ERROR_FAIL; + } + i++; +@@ -546,7 +552,7 @@ COMMAND_HANDLER(handle_svf_command) + free_all: + + fclose(svf_fd); +- svf_fd = 0; ++ svf_fd = NULL; + + /* free buffers */ + free(svf_command_buffer); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0101-svf-fix-memory-leak-on-error-during-command-executio.patch b/meta-oe/recipes-devtools/openocd/openocd/0101-svf-fix-memory-leak-on-error-during-command-executio.patch new file mode 100644 index 000000000..6576c7be9 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0101-svf-fix-memory-leak-on-error-during-command-executio.patch @@ -0,0 +1,68 @@ +From f8631c3650c0e3a3c3e16726f1ca3748d163cc69 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Fri, 10 Mar 2023 12:01:03 +0100 +Subject: [PATCH] svf: fix memory leak on error during command execution + +If svf_set_padding() returns error, jump to free_all label to +prevent any memory leak. +Propagate the error reported by svf_set_padding() instead of +overwriting it. +Use command_print() instead of LOG_ERROR() for command output. + +Change-Id: I61fd89cad10652f2f9ef1f9d48a040e35253c3d4 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7533 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/svf/svf.c | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +diff --git a/src/svf/svf.c b/src/svf/svf.c +index 05fb21d63..2a1331280 100644 +--- a/src/svf/svf.c ++++ b/src/svf/svf.c +@@ -473,27 +473,31 @@ COMMAND_HANDLER(handle_svf_command) + } + + /* HDR %d TDI (0) */ +- if (svf_set_padding(&svf_para.hdr_para, header_dr_len, 0) != ERROR_OK) { +- LOG_ERROR("failed to set data header"); +- return ERROR_FAIL; ++ ret = svf_set_padding(&svf_para.hdr_para, header_dr_len, 0); ++ if (ret != ERROR_OK) { ++ command_print(CMD, "failed to set data header"); ++ goto free_all; + } + + /* HIR %d TDI (0xFF) */ +- if (svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF) != ERROR_OK) { +- LOG_ERROR("failed to set instruction header"); +- return ERROR_FAIL; ++ ret = svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF); ++ if (ret != ERROR_OK) { ++ command_print(CMD, "failed to set instruction header"); ++ goto free_all; + } + + /* TDR %d TDI (0) */ +- if (svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0) != ERROR_OK) { +- LOG_ERROR("failed to set data trailer"); +- return ERROR_FAIL; ++ ret = svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0); ++ if (ret != ERROR_OK) { ++ command_print(CMD, "failed to set data trailer"); ++ goto free_all; + } + + /* TIR %d TDI (0xFF) */ +- if (svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF) != ERROR_OK) { +- LOG_ERROR("failed to set instruction trailer"); +- return ERROR_FAIL; ++ ret = svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF); ++ if (ret != ERROR_OK) { ++ command_print(CMD, "failed to set instruction trailer"); ++ goto free_all; + } + } + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0102-svf-make-command-svf-syntax-consistent.patch b/meta-oe/recipes-devtools/openocd/openocd/0102-svf-make-command-svf-syntax-consistent.patch new file mode 100644 index 000000000..43d335bc7 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0102-svf-make-command-svf-syntax-consistent.patch @@ -0,0 +1,218 @@ +From 5f6ceebbba3a34fc4bfcf56e963739dd2e9cf056 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Fri, 10 Mar 2023 11:41:54 +0100 +Subject: [PATCH] svf: make command 'svf' syntax consistent + +The command 'svf' is the only command in OpenOCD that accepts +options in both forms 'option' and '-option'. + +Deprecate the option format without the leading '-'. +Update the documentation and fix the on-line help. +While there: +- switch to use the new nvp.h helper; +- return ERROR_COMMAND_ARGUMENT_INVALID on invalid command args; +- fix some minor coding style rule. + +Change-Id: I5b944403d92a3fa1e12d5faafc1d2a139bc16a7d +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7534 +Tested-by: jenkins +--- + doc/openocd.texi | 12 +++--- + src/svf/svf.c | 95 +++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 83 insertions(+), 24 deletions(-) + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index 0de101b6d..26a59e6a7 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -11432,8 +11432,8 @@ way to represent JTAG test patterns in text files. + In a debug session using JTAG for its transport protocol, + OpenOCD supports running such test files. + +-@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{[-]quiet}] @ +- [@option{[-]nil}] [@option{[-]progress}] [@option{[-]ignore_error}] @ ++@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{-quiet}] @ ++ [@option{-nil}] [@option{-progress}] [@option{-ignore_error}] @ + [@option{-noreset}] [@option{-addcycles @var{cyclecount}}] + This issues a JTAG reset (Test-Logic-Reset) and then + runs the SVF script from @file{filename}. +@@ -11447,11 +11447,11 @@ Command options: + specified by the SVF file with HIR, TIR, HDR and TDR commands; + instead, calculate them automatically according to the current JTAG + chain configuration, targeting @var{tapname}; +-@item @option{[-]quiet} do not log every command before execution; +-@item @option{[-]nil} ``dry run'', i.e., do not perform any operations ++@item @option{-quiet} do not log every command before execution; ++@item @option{-nil} ``dry run'', i.e., do not perform any operations + on the real interface; +-@item @option{[-]progress} enable progress indication; +-@item @option{[-]ignore_error} continue execution despite TDO check ++@item @option{-progress} enable progress indication; ++@item @option{-ignore_error} continue execution despite TDO check + errors. + @item @option{-noreset} omit JTAG reset (Test-Logic-Reset) before executing + content of the SVF file; +diff --git a/src/svf/svf.c b/src/svf/svf.c +index 2a1331280..dd3d5175c 100644 +--- a/src/svf/svf.c ++++ b/src/svf/svf.c +@@ -22,6 +22,7 @@ + #include "svf.h" + #include "helper/system.h" + #include ++#include + #include + + /* SVF command */ +@@ -346,6 +347,37 @@ int svf_add_statemove(tap_state_t state_to) + return ERROR_FAIL; + } + ++enum svf_cmd_param { ++ OPT_ADDCYCLES, ++ OPT_IGNORE_ERROR, ++ OPT_NIL, ++ OPT_NORESET, ++ OPT_PROGRESS, ++ OPT_QUIET, ++ OPT_TAP, ++ /* DEPRECATED */ ++ DEPRECATED_OPT_IGNORE_ERROR, ++ DEPRECATED_OPT_NIL, ++ DEPRECATED_OPT_PROGRESS, ++ DEPRECATED_OPT_QUIET, ++}; ++ ++static const struct nvp svf_cmd_opts[] = { ++ { .name = "-addcycles", .value = OPT_ADDCYCLES }, ++ { .name = "-ignore_error", .value = OPT_IGNORE_ERROR }, ++ { .name = "-nil", .value = OPT_NIL }, ++ { .name = "-noreset", .value = OPT_NORESET }, ++ { .name = "-progress", .value = OPT_PROGRESS }, ++ { .name = "-quiet", .value = OPT_QUIET }, ++ { .name = "-tap", .value = OPT_TAP }, ++ /* DEPRECATED */ ++ { .name = "ignore_error", .value = DEPRECATED_OPT_IGNORE_ERROR }, ++ { .name = "nil", .value = DEPRECATED_OPT_NIL }, ++ { .name = "progress", .value = DEPRECATED_OPT_PROGRESS }, ++ { .name = "quiet", .value = DEPRECATED_OPT_QUIET }, ++ { .name = NULL, .value = -1 } ++}; ++ + COMMAND_HANDLER(handle_svf_command) + { + #define SVF_MIN_NUM_OF_OPTIONS 1 +@@ -355,10 +387,11 @@ COMMAND_HANDLER(handle_svf_command) + int64_t time_measure_ms; + int time_measure_s, time_measure_m; + +- /* use NULL to indicate a "plain" svf file which accounts for ++ /* ++ * use NULL to indicate a "plain" svf file which accounts for + * any additional devices in the scan chain, otherwise the device + * that should be affected +- */ ++ */ + struct jtag_tap *tap = NULL; + + if ((CMD_ARGC < SVF_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > SVF_MAX_NUM_OF_OPTIONS)) +@@ -373,48 +406,74 @@ COMMAND_HANDLER(handle_svf_command) + svf_addcycles = 0; + + for (unsigned int i = 0; i < CMD_ARGC; i++) { +- if (strcmp(CMD_ARGV[i], "-addcycles") == 0) { ++ const struct nvp *n = nvp_name2value(svf_cmd_opts, CMD_ARGV[i]); ++ switch (n->value) { ++ case OPT_ADDCYCLES: + svf_addcycles = atoi(CMD_ARGV[i + 1]); + if (svf_addcycles > SVF_MAX_ADDCYCLES) { + command_print(CMD, "addcycles: %s out of range", CMD_ARGV[i + 1]); + if (svf_fd) + fclose(svf_fd); + svf_fd = NULL; +- return ERROR_FAIL; ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + i++; +- } else if (strcmp(CMD_ARGV[i], "-tap") == 0) { ++ break; ++ ++ case OPT_TAP: + tap = jtag_tap_by_string(CMD_ARGV[i+1]); + if (!tap) { + command_print(CMD, "Tap: %s unknown", CMD_ARGV[i+1]); + if (svf_fd) + fclose(svf_fd); + svf_fd = NULL; +- return ERROR_FAIL; ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + i++; +- } else if ((strcmp(CMD_ARGV[i], +- "quiet") == 0) || (strcmp(CMD_ARGV[i], "-quiet") == 0)) ++ break; ++ ++ case DEPRECATED_OPT_QUIET: ++ LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); ++ /* fallthrough */ ++ case OPT_QUIET: + svf_quiet = 1; +- else if ((strcmp(CMD_ARGV[i], "nil") == 0) || (strcmp(CMD_ARGV[i], "-nil") == 0)) ++ break; ++ ++ case DEPRECATED_OPT_NIL: ++ LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); ++ /* fallthrough */ ++ case OPT_NIL: + svf_nil = 1; +- else if ((strcmp(CMD_ARGV[i], +- "progress") == 0) || (strcmp(CMD_ARGV[i], "-progress") == 0)) ++ break; ++ ++ case DEPRECATED_OPT_PROGRESS: ++ LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); ++ /* fallthrough */ ++ case OPT_PROGRESS: + svf_progress_enabled = 1; +- else if ((strcmp(CMD_ARGV[i], +- "ignore_error") == 0) || (strcmp(CMD_ARGV[i], "-ignore_error") == 0)) ++ break; ++ ++ case DEPRECATED_OPT_IGNORE_ERROR: ++ LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); ++ /* fallthrough */ ++ case OPT_IGNORE_ERROR: + svf_ignore_error = 1; +- else if (strcmp(CMD_ARGV[i], "-noreset") == 0) ++ break; ++ ++ case OPT_NORESET: + svf_noreset = true; +- else { ++ break; ++ ++ default: + svf_fd = fopen(CMD_ARGV[i], "r"); + if (!svf_fd) { + int err = errno; + command_print(CMD, "open(\"%s\"): %s", CMD_ARGV[i], strerror(err)); + /* no need to free anything now */ + return ERROR_COMMAND_SYNTAX_ERROR; +- } else +- LOG_USER("svf processing file: \"%s\"", CMD_ARGV[i]); ++ } ++ LOG_USER("svf processing file: \"%s\"", CMD_ARGV[i]); ++ break; + } + } + +@@ -1576,7 +1635,7 @@ static const struct command_registration svf_command_handlers[] = { + .handler = handle_svf_command, + .mode = COMMAND_EXEC, + .help = "Runs a SVF file.", +- .usage = "[-tap device.tap] [quiet] [nil] [progress] [ignore_error] [-noreset] [-addcycles numcycles]", ++ .usage = "[-tap device.tap] [-quiet] [-nil] [-progress] [-ignore_error] [-noreset] [-addcycles numcycles] file", + }, + COMMAND_REGISTRATION_DONE + }; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0103-helper-command-rewrite-command-ocd_find-as-COMMAND_H.patch b/meta-oe/recipes-devtools/openocd/openocd/0103-helper-command-rewrite-command-ocd_find-as-COMMAND_H.patch new file mode 100644 index 000000000..13d667171 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0103-helper-command-rewrite-command-ocd_find-as-COMMAND_H.patch @@ -0,0 +1,62 @@ +From 1ec8b83cbdb407536966b4e455dbb39d1cb42b3a Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 00:01:00 +0100 +Subject: [PATCH] helper: command: rewrite command 'ocd_find' as + COMMAND_HANDLER + +The mixed use of jim commands and OpenOCD commands is error prone +due to handling of errors through JIM_xx and ERROR_yy. + +Rewrite the jim command 'ocd_find' as OpenOCD command. + +Change-Id: Id775bccc12840bcf95d8c19787beda5e7c3107fc +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7484 +Reviewed-by: Tomas Vanek +Tested-by: jenkins +--- + src/helper/command.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/src/helper/command.c b/src/helper/command.c +index b358e18aa..235bec858 100644 +--- a/src/helper/command.c ++++ b/src/helper/command.c +@@ -662,19 +662,19 @@ void command_done(struct command_context *cmd_ctx) + } + + /* find full path to file */ +-static int jim_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_find) + { +- if (argc != 2) +- return JIM_ERR; +- const char *file = Jim_GetString(argv[1], NULL); +- char *full_path = find_file(file); ++ if (CMD_ARGC != 1) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ char *full_path = find_file(CMD_ARGV[0]); + if (!full_path) +- return JIM_ERR; +- Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path)); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ ++ command_print(CMD, "%s", full_path); + free(full_path); + +- Jim_SetResult(interp, result); +- return JIM_OK; ++ return ERROR_OK; + } + + COMMAND_HANDLER(handle_echo) +@@ -1165,7 +1165,7 @@ static const struct command_registration command_builtin_handlers[] = { + { + .name = "ocd_find", + .mode = COMMAND_ANY, +- .jim_handler = jim_find, ++ .handler = handle_find, + .help = "find full path to file", + .usage = "file", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0104-transport-rewrite-command-transport-select-as-COMMAN.patch b/meta-oe/recipes-devtools/openocd/openocd/0104-transport-rewrite-command-transport-select-as-COMMAN.patch new file mode 100644 index 000000000..1f3ab3283 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0104-transport-rewrite-command-transport-select-as-COMMAN.patch @@ -0,0 +1,149 @@ +From d05c68667129705ecfd42c6029a60e849518d50c Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 18 Dec 2022 15:26:56 +0100 +Subject: [PATCH] transport: rewrite command 'transport select' as + COMMAND_HANDLER + +The mixed use of jim commands and OpenOCD commands is error prone +due to handling of errors through JIM_xx and ERROR_yy. + +Rewrite the jim command 'transport select' as OpenOCD command. +This fixes and incorrect check for the return value of function +transport_select(); it returns ERROR_yy but the check is on JIM_xx. +While there, fix the coding style. + +Change-Id: I9f3e8394c1a0cc0312b414c58275e1220217bbed +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7485 +Reviewed-by: Tomas Vanek +Tested-by: jenkins +--- + src/transport/transport.c | 100 +++++++++++++++++++------------------- + 1 file changed, 49 insertions(+), 51 deletions(-) + +diff --git a/src/transport/transport.c b/src/transport/transport.c +index c05db3f00..81d3d583b 100644 +--- a/src/transport/transport.c ++++ b/src/transport/transport.c +@@ -252,64 +252,62 @@ COMMAND_HANDLER(handle_transport_list) + * set supported by the debug adapter being used. Return value + * is scriptable (allowing "if swd then..." etc). + */ +-static int jim_transport_select(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(handle_transport_select) + { +- int res; +- switch (argc) { +- case 1: /* autoselect if necessary, then return/display current config */ +- if (!session) { +- if (!allowed_transports) { +- LOG_ERROR("Debug adapter does not support any transports? Check config file order."); +- return JIM_ERR; +- } +- LOG_INFO("auto-selecting first available session transport \"%s\". " +- "To override use 'transport select '.", allowed_transports[0]); +- res = transport_select(global_cmd_ctx, allowed_transports[0]); +- if (res != JIM_OK) +- return res; +- } +- Jim_SetResultString(interp, session->name, -1); +- return JIM_OK; +- case 2: /* assign */ +- if (session) { +- if (!strcmp(session->name, argv[1]->bytes)) { +- LOG_WARNING("Transport \"%s\" was already selected", session->name); +- Jim_SetResultString(interp, session->name, -1); +- return JIM_OK; +- } else { +- LOG_ERROR("Can't change session's transport after the initial selection was made"); +- return JIM_ERR; +- } +- } ++ if (CMD_ARGC > 1) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- /* Is this transport supported by our debug adapter? +- * Example, "JTAG-only" means SWD is not supported. +- * +- * NOTE: requires adapter to have been set up, with +- * transports declared via C. +- */ ++ if (CMD_ARGC == 0) { ++ /* autoselect if necessary, then return/display current config */ ++ if (!session) { + if (!allowed_transports) { +- LOG_ERROR("Debug adapter doesn't support any transports?"); +- return JIM_ERR; ++ command_print(CMD, "Debug adapter does not support any transports? Check config file order."); ++ return ERROR_FAIL; + } ++ LOG_INFO("auto-selecting first available session transport \"%s\". " ++ "To override use 'transport select '.", allowed_transports[0]); ++ int retval = transport_select(CMD_CTX, allowed_transports[0]); ++ if (retval != ERROR_OK) ++ return retval; ++ } ++ command_print(CMD, "%s", session->name); ++ return ERROR_OK; ++ } + +- for (unsigned i = 0; allowed_transports[i]; i++) { ++ /* assign transport */ ++ if (session) { ++ if (!strcmp(session->name, CMD_ARGV[0])) { ++ LOG_WARNING("Transport \"%s\" was already selected", session->name); ++ command_print(CMD, "%s", session->name); ++ return ERROR_OK; ++ } ++ command_print(CMD, "Can't change session's transport after the initial selection was made"); ++ return ERROR_FAIL; ++ } + +- if (strcmp(allowed_transports[i], argv[1]->bytes) == 0) { +- if (transport_select(global_cmd_ctx, argv[1]->bytes) == ERROR_OK) { +- Jim_SetResultString(interp, session->name, -1); +- return JIM_OK; +- } +- return JIM_ERR; +- } +- } ++ /* Is this transport supported by our debug adapter? ++ * Example, "JTAG-only" means SWD is not supported. ++ * ++ * NOTE: requires adapter to have been set up, with ++ * transports declared via C. ++ */ ++ if (!allowed_transports) { ++ command_print(CMD, "Debug adapter doesn't support any transports?"); ++ return ERROR_FAIL; ++ } + +- LOG_ERROR("Debug adapter doesn't support '%s' transport", argv[1]->bytes); +- return JIM_ERR; +- default: +- Jim_WrongNumArgs(interp, 1, argv, "[too many parameters]"); +- return JIM_ERR; ++ for (unsigned int i = 0; allowed_transports[i]; i++) { ++ if (!strcmp(allowed_transports[i], CMD_ARGV[0])) { ++ int retval = transport_select(CMD_CTX, CMD_ARGV[0]); ++ if (retval != ERROR_OK) ++ return retval; ++ command_print(CMD, "%s", session->name); ++ return ERROR_OK; ++ } + } ++ ++ command_print(CMD, "Debug adapter doesn't support '%s' transport", CMD_ARGV[0]); ++ return ERROR_FAIL; + } + + static const struct command_registration transport_commands[] = { +@@ -333,7 +331,7 @@ static const struct command_registration transport_commands[] = { + }, + { + .name = "select", +- .jim_handler = jim_transport_select, ++ .handler = handle_transport_select, + .mode = COMMAND_ANY, + .help = "Select this session's transport", + .usage = "[transport_name]", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0105-flash-nor-rewrite-command-flash-list-as-COMMAND_HAND.patch b/meta-oe/recipes-devtools/openocd/openocd/0105-flash-nor-rewrite-command-flash-list-as-COMMAND_HAND.patch new file mode 100644 index 000000000..328a838f3 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0105-flash-nor-rewrite-command-flash-list-as-COMMAND_HAND.patch @@ -0,0 +1,95 @@ +From 80fc9fabc66a0bc767467fa14c703e5a9f340cd3 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 18 Dec 2022 16:09:02 +0100 +Subject: [PATCH] flash: nor: rewrite command 'flash list' as COMMAND_HANDLER + +The mixed use of jim commands and OpenOCD commands is error prone +due to handling of errors through JIM_xx and ERROR_yy. + +Rewrite the jim command 'flash list' as OpenOCD command. +While there: +- format in a human readable way the output dictionary list, while + preserving the structure of its TCL data; +- add the mandatory 'usage' field. + +Change-Id: I1ee69870d3ab3c1cfc46cd2b8ec03de6b2300bd6 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7486 +Reviewed-by: Tomas Vanek +Tested-by: jenkins +--- + src/flash/nor/tcl.c | 48 +++++++++++++++++---------------------------- + 1 file changed, 18 insertions(+), 30 deletions(-) + +diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c +index 4ff6d9838..ecbcf00aa 100644 +--- a/src/flash/nor/tcl.c ++++ b/src/flash/nor/tcl.c +@@ -1324,40 +1324,27 @@ COMMAND_HANDLER(handle_flash_banks_command) + return ERROR_OK; + } + +-static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(handle_flash_list) + { +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, +- "no arguments to 'flash list' command"); +- return JIM_ERR; +- } +- +- Jim_Obj *list = Jim_NewListObj(interp, NULL, 0); ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + + for (struct flash_bank *p = flash_bank_list(); p; p = p->next) { +- Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0); +- +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->name, -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "driver", -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "target", -1)); +- Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, target_name(p->target), -1)); +- +- Jim_ListAppendElement(interp, list, elem); ++ command_print(CMD, ++ "{\n" ++ " name %s\n" ++ " driver %s\n" ++ " base " TARGET_ADDR_FMT "\n" ++ " size 0x%" PRIx32 "\n" ++ " bus_width %u\n" ++ " chip_width %u\n" ++ " target %s\n" ++ "}", ++ p->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width, ++ target_name(p->target)); + } + +- Jim_SetResult(interp, list); +- +- return JIM_OK; ++ return ERROR_OK; + } + + COMMAND_HANDLER(handle_flash_init_command) +@@ -1404,8 +1391,9 @@ static const struct command_registration flash_config_command_handlers[] = { + { + .name = "list", + .mode = COMMAND_ANY, +- .jim_handler = jim_flash_list, ++ .handler = handle_flash_list, + .help = "Returns a list of details about the flash banks.", ++ .usage = "", + }, + COMMAND_REGISTRATION_DONE + }; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0106-helper-util-rewrite-command-ms-as-COMMAND_HANDLER.patch b/meta-oe/recipes-devtools/openocd/openocd/0106-helper-util-rewrite-command-ms-as-COMMAND_HANDLER.patch new file mode 100644 index 000000000..efce23f3c --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0106-helper-util-rewrite-command-ms-as-COMMAND_HANDLER.patch @@ -0,0 +1,55 @@ +From 842a12f4caf307e756045c14011c402a20da30b6 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 18 Dec 2022 18:49:02 +0100 +Subject: [PATCH] helper: util: rewrite command 'ms' as COMMAND_HANDLER + +Use full 64 bits in output; no reason to truncate at 32 bits. + +Change-Id: I433815a381e147731ff0da2c805170649a9bcf38 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7487 +Reviewed-by: Tomas Vanek +Tested-by: jenkins +--- + src/helper/util.c | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +diff --git a/src/helper/util.c b/src/helper/util.c +index bf18f8e60..5e12021ff 100644 +--- a/src/helper/util.c ++++ b/src/helper/util.c +@@ -13,28 +13,21 @@ + #include "log.h" + #include "time_support.h" + +-static int jim_util_ms(Jim_Interp *interp, +- int argc, +- Jim_Obj * const *argv) ++COMMAND_HANDLER(handler_util_ms) + { +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?"); +- return JIM_ERR; +- } ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- /* Cast from 64 to 32 bit int works for 2's-compliment +- * when calculating differences*/ +- Jim_SetResult(interp, Jim_NewIntObj(interp, (int)timeval_ms())); ++ command_print(CMD, "%" PRId64, timeval_ms()); + +- return JIM_OK; ++ return ERROR_OK; + } + + static const struct command_registration util_command_handlers[] = { +- /* jim handlers */ + { + .name = "ms", + .mode = COMMAND_ANY, +- .jim_handler = jim_util_ms, ++ .handler = handler_util_ms, + .help = + "Returns ever increasing milliseconds. Used to calculate differences in time.", + .usage = "", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0107-openocd-rewrite-command-version-as-COMMAND_HANDLER.patch b/meta-oe/recipes-devtools/openocd/openocd/0107-openocd-rewrite-command-version-as-COMMAND_HANDLER.patch new file mode 100644 index 000000000..d25471fe4 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0107-openocd-rewrite-command-version-as-COMMAND_HANDLER.patch @@ -0,0 +1,89 @@ +From 880ae3f07744a09e267bde00cf405c85a6f10482 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 18 Dec 2022 19:12:35 +0100 +Subject: [PATCH] openocd: rewrite command 'version' as COMMAND_HANDLER + +Trivial change. +While there: +- add the mandatory 'usage' field; +- document the optional parameter 'git'; +- reword the documentation. + +Change-Id: I6be4d4423128fa026a62e2ef355f77b69d50397e +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7488 +Tested-by: jenkins +--- + doc/openocd.texi | 6 ++++-- + src/openocd.c | 26 +++++++++++++------------- + 2 files changed, 17 insertions(+), 15 deletions(-) + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index 26a59e6a7..67661845d 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -9101,8 +9101,10 @@ format. Optional @option{start} and @option{end} parameters allow to + limit the address range. + @end deffn + +-@deffn {Command} {version} +-Displays a string identifying the version of this OpenOCD server. ++@deffn {Command} {version} [git] ++Returns a string identifying the version of this OpenOCD server. ++With option @option{git}, it returns the git version obtained at compile time ++through ``git describe''. + @end deffn + + @deffn {Command} {virt2phys} virtual_address +diff --git a/src/openocd.c b/src/openocd.c +index 875da5a62..54c5eb34f 100644 +--- a/src/openocd.c ++++ b/src/openocd.c +@@ -51,24 +51,23 @@ static const char openocd_startup_tcl[] = { + }; + + /* Give scripts and TELNET a way to find out what version this is */ +-static int jim_version_command(Jim_Interp *interp, int argc, +- Jim_Obj * const *argv) ++COMMAND_HANDLER(handler_version_command) + { +- if (argc > 2) +- return JIM_ERR; +- const char *str = ""; +- char *version_str; +- version_str = OPENOCD_VERSION; ++ char *version_str = OPENOCD_VERSION; + +- if (argc == 2) +- str = Jim_GetString(argv[1], NULL); ++ if (CMD_ARGC > 1) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ if (CMD_ARGC == 1) { ++ if (strcmp("git", CMD_ARGV[0])) ++ return ERROR_COMMAND_ARGUMENT_INVALID; + +- if (strcmp("git", str) == 0) + version_str = GITVERSION; ++ } + +- Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1)); ++ command_print(CMD, "%s", version_str); + +- return JIM_OK; ++ return ERROR_OK; + } + + static int log_target_callback_event_handler(struct target *target, +@@ -194,9 +193,10 @@ COMMAND_HANDLER(handle_add_script_search_dir_command) + static const struct command_registration openocd_command_handlers[] = { + { + .name = "version", +- .jim_handler = jim_version_command, ++ .handler = handler_version_command, + .mode = COMMAND_ANY, + .help = "show program version", ++ .usage = "[git]", + }, + { + .name = "noinit", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0108-rtt-rewrite-command-rtt-channellist-as-COMMAND_HANDL.patch b/meta-oe/recipes-devtools/openocd/openocd/0108-rtt-rewrite-command-rtt-channellist-as-COMMAND_HANDL.patch new file mode 100644 index 000000000..c4bbbcc9c --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0108-rtt-rewrite-command-rtt-channellist-as-COMMAND_HANDL.patch @@ -0,0 +1,158 @@ +From 0332da1f1518b0cb4150965614c09fcc7319ddbe Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 18 Dec 2022 22:42:18 +0100 +Subject: [PATCH] rtt: rewrite command 'rtt channellist' as COMMAND_HANDLER + +This also fixes a mistake of the jim command returning ERROR_xx +when function rtt_read_channel_info() returns error. +While there: +- format in a human readable way the output dictionary list, while + preserving the structure of its TCL data; +- add check for the number of parameters. + +Change-Id: Ica2b623699d3a606d3992975c836dae96f74b26d +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7489 +Tested-by: jenkins +--- + src/rtt/tcl.c | 86 ++++++++++++++++----------------------------------- + 1 file changed, 26 insertions(+), 60 deletions(-) + +diff --git a/src/rtt/tcl.c b/src/rtt/tcl.c +index 7cbdccf56..f949aa1c9 100644 +--- a/src/rtt/tcl.c ++++ b/src/rtt/tcl.c +@@ -150,17 +150,17 @@ COMMAND_HANDLER(handle_rtt_channels_command) + return ERROR_OK; + } + +-static int jim_channel_list(Jim_Interp *interp, int argc, +- Jim_Obj * const *argv) ++COMMAND_HANDLER(handle_channel_list) + { +- Jim_Obj *list; +- Jim_Obj *channel_list; + char channel_name[CHANNEL_NAME_SIZE]; + const struct rtt_control *ctrl; + struct rtt_channel_info info; + ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ + if (!rtt_found_cb()) { +- Jim_SetResultFormatted(interp, "rtt: Control block not available"); ++ command_print(CMD, "rtt: Control block not available"); + return ERROR_FAIL; + } + +@@ -169,81 +169,47 @@ static int jim_channel_list(Jim_Interp *interp, int argc, + info.name = channel_name; + info.name_length = sizeof(channel_name); + +- list = Jim_NewListObj(interp, NULL, 0); +- channel_list = Jim_NewListObj(interp, NULL, 0); ++ command_print(CMD, "{"); + + for (unsigned int i = 0; i < ctrl->num_up_channels; i++) { +- int ret; +- Jim_Obj *tmp; +- +- ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info); +- ++ int ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info); + if (ret != ERROR_OK) + return ret; + + if (!info.size) + continue; + +- tmp = Jim_NewListObj(interp, NULL, 0); +- +- Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, +- "name", -1)); +- Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, +- info.name, -1)); +- +- Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, +- "size", -1)); +- Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, +- info.size)); +- +- Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, +- "flags", -1)); +- Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, +- info.flags)); +- +- Jim_ListAppendElement(interp, channel_list, tmp); ++ command_print(CMD, ++ " {\n" ++ " name %s\n" ++ " size 0x%" PRIx32 "\n" ++ " flags 0x%" PRIx32 "\n" ++ " }", ++ info.name, info.size, info.flags); + } + +- Jim_ListAppendElement(interp, list, channel_list); +- +- channel_list = Jim_NewListObj(interp, NULL, 0); ++ command_print(CMD, "}\n{"); + + for (unsigned int i = 0; i < ctrl->num_down_channels; i++) { +- int ret; +- Jim_Obj *tmp; +- +- ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info); +- ++ int ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info); + if (ret != ERROR_OK) + return ret; + + if (!info.size) + continue; + +- tmp = Jim_NewListObj(interp, NULL, 0); +- +- Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, +- "name", -1)); +- Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, +- info.name, -1)); +- +- Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, +- "size", -1)); +- Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, +- info.size)); +- +- Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, +- "flags", -1)); +- Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, +- info.flags)); +- +- Jim_ListAppendElement(interp, channel_list, tmp); ++ command_print(CMD, ++ " {\n" ++ " name %s\n" ++ " size 0x%" PRIx32 "\n" ++ " flags 0x%" PRIx32 "\n" ++ " }", ++ info.name, info.size, info.flags); + } + +- Jim_ListAppendElement(interp, list, channel_list); +- Jim_SetResult(interp, list); ++ command_print(CMD, "}"); + +- return JIM_OK; ++ return ERROR_OK; + } + + static const struct command_registration rtt_subcommand_handlers[] = { +@@ -284,7 +250,7 @@ static const struct command_registration rtt_subcommand_handlers[] = { + }, + { + .name = "channellist", +- .jim_handler = jim_channel_list, ++ .handler = handle_channel_list, + .mode = COMMAND_EXEC, + .help = "list available channels", + .usage = "" diff --git a/meta-oe/recipes-devtools/openocd/openocd/0109-target-aarch64-rewrite-commands-aarch64-mcr-mrc-as-C.patch b/meta-oe/recipes-devtools/openocd/openocd/0109-target-aarch64-rewrite-commands-aarch64-mcr-mrc-as-C.patch new file mode 100644 index 000000000..378b98a19 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0109-target-aarch64-rewrite-commands-aarch64-mcr-mrc-as-C.patch @@ -0,0 +1,224 @@ +From 21e6252965d8cf82660344a7d6c12d64269d7387 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 12:49:20 +0100 +Subject: [PATCH] target: aarch64: rewrite commands 'aarch64 mcr/mrc' as + COMMAND_HANDLER + +This also fixes an incorrect return ERROR_TARGET_NOT_HALTED from a +jim command. + +Change-Id: I99a02a21bedb64e60944e295c7cf24356e07be60 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7490 +Tested-by: jenkins +--- + src/target/aarch64.c | 129 +++++++++++++++---------------------------- + 1 file changed, 46 insertions(+), 83 deletions(-) + +diff --git a/src/target/aarch64.c b/src/target/aarch64.c +index 8e90e6400..3c33032e9 100644 +--- a/src/target/aarch64.c ++++ b/src/target/aarch64.c +@@ -2952,53 +2952,41 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) + return ERROR_OK; + } + +-static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(aarch64_mcrmrc_command) + { +- struct command *c = jim_to_command(interp); +- struct command_context *context; +- struct target *target; +- struct arm *arm; +- int retval; + bool is_mcr = false; +- int arg_cnt = 0; ++ unsigned int arg_cnt = 5; + +- if (!strcmp(c->name, "mcr")) { ++ if (!strcmp(CMD_NAME, "mcr")) { + is_mcr = true; +- arg_cnt = 7; +- } else { + arg_cnt = 6; + } + +- context = current_command_context(interp); +- assert(context); ++ if (arg_cnt != CMD_ARGC) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- target = get_current_target(context); ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- LOG_ERROR("%s: no current target", __func__); +- return JIM_ERR; ++ command_print(CMD, "no current target"); ++ return ERROR_FAIL; + } + if (!target_was_examined(target)) { +- LOG_ERROR("%s: not yet examined", target_name(target)); +- return JIM_ERR; ++ command_print(CMD, "%s: not yet examined", target_name(target)); ++ return ERROR_TARGET_NOT_EXAMINED; + } + +- arm = target_to_arm(target); ++ struct arm *arm = target_to_arm(target); + if (!is_arm(arm)) { +- LOG_ERROR("%s: not an ARM", target_name(target)); +- return JIM_ERR; ++ command_print(CMD, "%s: not an ARM", target_name(target)); ++ return ERROR_FAIL; + } + + if (target->state != TARGET_HALTED) + return ERROR_TARGET_NOT_HALTED; + + if (arm->core_state == ARM_STATE_AARCH64) { +- LOG_ERROR("%s: not 32-bit arm target", target_name(target)); +- return JIM_ERR; +- } +- +- if (argc != arg_cnt) { +- LOG_ERROR("%s: wrong number of arguments", __func__); +- return JIM_ERR; ++ command_print(CMD, "%s: not 32-bit arm target", target_name(target)); ++ return ERROR_FAIL; + } + + int cpnum; +@@ -3007,87 +2995,62 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) + uint32_t crn; + uint32_t crm; + uint32_t value; +- long l; + + /* NOTE: parameter sequence matches ARM instruction set usage: + * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX + * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX + * The "rX" is necessarily omitted; it uses Tcl mechanisms. + */ +- retval = Jim_GetLong(interp, argv[1], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0xf) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "coprocessor", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum); ++ if (cpnum & ~0xf) { ++ command_print(CMD, "coprocessor %d out of range", cpnum); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- cpnum = l; + +- retval = Jim_GetLong(interp, argv[2], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0x7) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "op1", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1); ++ if (op1 & ~0x7) { ++ command_print(CMD, "op1 %d out of range", op1); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- op1 = l; + +- retval = Jim_GetLong(interp, argv[3], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0xf) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "CRn", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn); ++ if (crn & ~0xf) { ++ command_print(CMD, "CRn %d out of range", crn); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- crn = l; + +- retval = Jim_GetLong(interp, argv[4], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0xf) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "CRm", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm); ++ if (crm & ~0xf) { ++ command_print(CMD, "CRm %d out of range", crm); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- crm = l; + +- retval = Jim_GetLong(interp, argv[5], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0x7) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "op2", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2); ++ if (op2 & ~0x7) { ++ command_print(CMD, "op2 %d out of range", op2); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- op2 = l; + +- value = 0; +- +- if (is_mcr == true) { +- retval = Jim_GetLong(interp, argv[6], &l); +- if (retval != JIM_OK) +- return retval; +- value = l; ++ if (is_mcr) { ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value); + + /* NOTE: parameters reordered! */ + /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ +- retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); ++ int retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); + if (retval != ERROR_OK) +- return JIM_ERR; ++ return retval; + } else { ++ value = 0; + /* NOTE: parameters reordered! */ + /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ +- retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); ++ int retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); + if (retval != ERROR_OK) +- return JIM_ERR; ++ return retval; + +- Jim_SetResult(interp, Jim_NewIntObj(interp, value)); ++ command_print(CMD, "0x%" PRIx32, value); + } + +- return JIM_OK; ++ return ERROR_OK; + } + + static const struct command_registration aarch64_exec_command_handlers[] = { +@@ -3122,14 +3085,14 @@ static const struct command_registration aarch64_exec_command_handlers[] = { + { + .name = "mcr", + .mode = COMMAND_EXEC, +- .jim_handler = jim_mcrmrc, ++ .handler = aarch64_mcrmrc_command, + .help = "write coprocessor register", + .usage = "cpnum op1 CRn CRm op2 value", + }, + { + .name = "mrc", + .mode = COMMAND_EXEC, +- .jim_handler = jim_mcrmrc, ++ .handler = aarch64_mcrmrc_command, + .help = "read coprocessor register", + .usage = "cpnum op1 CRn CRm op2", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0110-target-armv4_5-rewrite-commands-arm-mcr-mrc-as-COMMA.patch b/meta-oe/recipes-devtools/openocd/openocd/0110-target-armv4_5-rewrite-commands-arm-mcr-mrc-as-COMMA.patch new file mode 100644 index 000000000..d4167911e --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0110-target-armv4_5-rewrite-commands-arm-mcr-mrc-as-COMMA.patch @@ -0,0 +1,222 @@ +From c4f2337d02d3c0d452a9958e44e82a8e6454dead Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 13:02:59 +0100 +Subject: [PATCH] target: armv4_5: rewrite commands 'arm mcr/mrc' as + COMMAND_HANDLER + +While there, add a check for target halted and check the number of +parameters accordingly to the command name. + +Change-Id: I9e8bb109c35039561997d14782fac682267aee65 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7491 +Tested-by: jenkins +--- + src/target/armv4_5.c | 132 +++++++++++++++++-------------------------- + 1 file changed, 53 insertions(+), 79 deletions(-) + +diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c +index 48af5035a..9586adc97 100644 +--- a/src/target/armv4_5.c ++++ b/src/target/armv4_5.c +@@ -989,36 +989,37 @@ COMMAND_HANDLER(handle_arm_disassemble_command) + #endif + } + +-static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(handle_armv4_5_mcrmrc) + { +- struct command_context *context; +- struct target *target; +- struct arm *arm; +- int retval; ++ bool is_mcr = false; ++ unsigned int arg_cnt = 5; ++ ++ if (!strcmp(CMD_NAME, "mcr")) { ++ is_mcr = true; ++ arg_cnt = 6; ++ } + +- context = current_command_context(interp); +- assert(context); ++ if (arg_cnt != CMD_ARGC) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- target = get_current_target(context); ++ struct target *target = get_current_target(CMD_CTX); + if (!target) { +- LOG_ERROR("%s: no current target", __func__); +- return JIM_ERR; ++ command_print(CMD, "no current target"); ++ return ERROR_FAIL; + } + if (!target_was_examined(target)) { +- LOG_ERROR("%s: not yet examined", target_name(target)); +- return JIM_ERR; ++ command_print(CMD, "%s: not yet examined", target_name(target)); ++ return ERROR_TARGET_NOT_EXAMINED; + } +- arm = target_to_arm(target); ++ ++ struct arm *arm = target_to_arm(target); + if (!is_arm(arm)) { +- LOG_ERROR("%s: not an ARM", target_name(target)); +- return JIM_ERR; ++ command_print(CMD, "%s: not an ARM", target_name(target)); ++ return ERROR_FAIL; + } + +- if ((argc < 6) || (argc > 7)) { +- /* FIXME use the command name to verify # params... */ +- LOG_ERROR("%s: wrong number of arguments", __func__); +- return JIM_ERR; +- } ++ if (target->state != TARGET_HALTED) ++ return ERROR_TARGET_NOT_HALTED; + + int cpnum; + uint32_t op1; +@@ -1026,95 +1027,68 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) + uint32_t crn; + uint32_t crm; + uint32_t value; +- long l; + + /* NOTE: parameter sequence matches ARM instruction set usage: + * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX + * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX + * The "rX" is necessarily omitted; it uses Tcl mechanisms. + */ +- retval = Jim_GetLong(interp, argv[1], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0xf) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "coprocessor", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum); ++ if (cpnum & ~0xf) { ++ command_print(CMD, "coprocessor %d out of range", cpnum); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- cpnum = l; + +- retval = Jim_GetLong(interp, argv[2], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0x7) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "op1", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1); ++ if (op1 & ~0x7) { ++ command_print(CMD, "op1 %d out of range", op1); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- op1 = l; + +- retval = Jim_GetLong(interp, argv[3], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0xf) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "CRn", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn); ++ if (crn & ~0xf) { ++ command_print(CMD, "CRn %d out of range", crn); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- crn = l; + +- retval = Jim_GetLong(interp, argv[4], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0xf) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "CRm", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm); ++ if (crm & ~0xf) { ++ command_print(CMD, "CRm %d out of range", crm); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- crm = l; + +- retval = Jim_GetLong(interp, argv[5], &l); +- if (retval != JIM_OK) +- return retval; +- if (l & ~0x7) { +- LOG_ERROR("%s: %s %d out of range", __func__, +- "op2", (int) l); +- return JIM_ERR; ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2); ++ if (op2 & ~0x7) { ++ command_print(CMD, "op2 %d out of range", op2); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } +- op2 = l; +- +- value = 0; + +- /* FIXME don't assume "mrc" vs "mcr" from the number of params; +- * that could easily be a typo! Check both... +- * ++ /* + * FIXME change the call syntax here ... simplest to just pass + * the MRC() or MCR() instruction to be executed. That will also + * let us support the "mrc2" and "mcr2" opcodes (toggling one bit) + * if that's ever needed. + */ +- if (argc == 7) { +- retval = Jim_GetLong(interp, argv[6], &l); +- if (retval != JIM_OK) +- return retval; +- value = l; ++ if (is_mcr) { ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value); + + /* NOTE: parameters reordered! */ + /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ +- retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); ++ int retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); + if (retval != ERROR_OK) +- return JIM_ERR; ++ return retval; + } else { ++ value = 0; + /* NOTE: parameters reordered! */ + /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ +- retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); ++ int retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); + if (retval != ERROR_OK) +- return JIM_ERR; ++ return retval; + +- Jim_SetResult(interp, Jim_NewIntObj(interp, value)); ++ command_print(CMD, "0x%" PRIx32, value); + } + +- return JIM_OK; ++ return ERROR_OK; + } + + static const struct command_registration arm_exec_command_handlers[] = { +@@ -1128,14 +1102,14 @@ static const struct command_registration arm_exec_command_handlers[] = { + { + .name = "mcr", + .mode = COMMAND_EXEC, +- .jim_handler = &jim_mcrmrc, ++ .handler = handle_armv4_5_mcrmrc, + .help = "write coprocessor register", + .usage = "cpnum op1 CRn CRm op2 value", + }, + { + .name = "mrc", + .mode = COMMAND_EXEC, +- .jim_handler = &jim_mcrmrc, ++ .handler = handle_armv4_5_mcrmrc, + .help = "read coprocessor register", + .usage = "cpnum op1 CRn CRm op2", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0111-target-cti-rewrite-command-cti-names-as-COMMAND_HAND.patch b/meta-oe/recipes-devtools/openocd/openocd/0111-target-cti-rewrite-command-cti-names-as-COMMAND_HAND.patch new file mode 100644 index 000000000..9c7961460 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0111-target-cti-rewrite-command-cti-names-as-COMMAND_HAND.patch @@ -0,0 +1,58 @@ +From 5da4ef25c8a2e57325bc1706c07f54cc99ce0ce1 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 17:55:13 +0100 +Subject: [PATCH] target: cti: rewrite command 'cti names' as COMMAND_HANDLER + +While there, format in a human readable way the output list by +using one line per cti name. + +Change-Id: I6d4870ee512fe7e6935d73355c2377ad805ccc3b +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7492 +Tested-by: jenkins +--- + src/target/arm_cti.c | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c +index 3612874e2..7637ad015 100644 +--- a/src/target/arm_cti.c ++++ b/src/target/arm_cti.c +@@ -525,20 +525,17 @@ static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) + return cti_create(&goi); + } + +-static int jim_cti_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(cti_handle_names) + { + struct arm_cti *obj; + +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } +- Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); +- list_for_each_entry(obj, &all_cti, lh) { +- Jim_ListAppendElement(interp, Jim_GetResult(interp), +- Jim_NewStringObj(interp, obj->name, -1)); +- } +- return JIM_OK; ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ list_for_each_entry(obj, &all_cti, lh) ++ command_print(CMD, "%s", obj->name); ++ ++ return ERROR_OK; + } + + +@@ -553,7 +550,7 @@ static const struct command_registration cti_subcommand_handlers[] = { + { + .name = "names", + .mode = COMMAND_ANY, +- .jim_handler = jim_cti_names, ++ .handler = cti_handle_names, + .usage = "", + .help = "Lists all registered CTI objects by name", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0112-jtag-rewrite-command-adapter-name-as-COMMAND_HANDLER.patch b/meta-oe/recipes-devtools/openocd/openocd/0112-jtag-rewrite-command-adapter-name-as-COMMAND_HANDLER.patch new file mode 100644 index 000000000..abdaba97f --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0112-jtag-rewrite-command-adapter-name-as-COMMAND_HANDLER.patch @@ -0,0 +1,62 @@ +From 19e2a0d6af3783e572a80e4cbf0f471f6dbf66e7 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 18 Dec 2022 22:11:14 +0100 +Subject: [PATCH] jtag: rewrite command 'adapter name' as COMMAND_HANDLER + +Trivial change. +Add the mandatory 'usage' field. + +Change-Id: Id92af5cd873fb86f5de79f785f156d1ef734b005 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7493 +Tested-by: jenkins +--- + src/jtag/adapter.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c +index eb73fcb9a..76a6620be 100644 +--- a/src/jtag/adapter.c ++++ b/src/jtag/adapter.c +@@ -378,21 +378,18 @@ done: + return equal; + } + +-static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(handle_adapter_name) + { +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc-1, argv + 1); +- + /* return the name of the interface */ + /* TCL code might need to know the exact type... */ + /* FUTURE: we allow this as a means to "set" the interface. */ +- if (goi.argc != 0) { +- Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); +- return JIM_ERR; +- } +- const char *name = adapter_driver ? adapter_driver->name : NULL; +- Jim_SetResultString(goi.interp, name ? name : "undefined", -1); +- return JIM_OK; ++ ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ command_print(CMD, "%s", adapter_driver ? adapter_driver->name : "undefined"); ++ ++ return ERROR_OK; + } + + COMMAND_HANDLER(adapter_transports_command) +@@ -1127,9 +1124,10 @@ static const struct command_registration adapter_command_handlers[] = { + { + .name = "name", + .mode = COMMAND_ANY, +- .jim_handler = jim_adapter_name, ++ .handler = handle_adapter_name, + .help = "Returns the name of the currently " + "selected adapter (driver)", ++ .usage = "", + }, + { + .name = "srst", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0113-jtag-rewrite-command-jtag-names-as-COMMAND_HANDLER.patch b/meta-oe/recipes-devtools/openocd/openocd/0113-jtag-rewrite-command-jtag-names-as-COMMAND_HANDLER.patch new file mode 100644 index 000000000..171a9bd48 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0113-jtag-rewrite-command-jtag-names-as-COMMAND_HANDLER.patch @@ -0,0 +1,65 @@ +From 27741252571d7c34b9049275d02cf6c34b1ae7d2 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 18:08:03 +0100 +Subject: [PATCH] jtag: rewrite command 'jtag names' as COMMAND_HANDLER + +While there: +- format in a human readable way the output list by using one line + per tap name; +- add the mandatory 'usage' field. + +Change-Id: I295449220c78fac8973478b265413342ea832f61 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7494 +Tested-by: jenkins +--- + src/jtag/tcl.c | 26 +++++++++----------------- + 1 file changed, 9 insertions(+), 17 deletions(-) + +diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c +index fc0d562e2..83cb0a18b 100644 +--- a/src/jtag/tcl.c ++++ b/src/jtag/tcl.c +@@ -805,24 +805,15 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) + return jtag_tap_configure_cmd(&goi, t); + } + +-static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_jtag_names) + { +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc-1, argv + 1); +- if (goi.argc != 0) { +- Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters"); +- return JIM_ERR; +- } +- Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0)); +- struct jtag_tap *tap; ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- for (tap = jtag_all_taps(); tap; tap = tap->next_tap) { +- Jim_ListAppendElement(goi.interp, +- Jim_GetResult(goi.interp), +- Jim_NewStringObj(goi.interp, +- tap->dotted_name, -1)); +- } +- return JIM_OK; ++ for (struct jtag_tap *tap = jtag_all_taps(); tap; tap = tap->next_tap) ++ command_print(CMD, "%s", tap->dotted_name); ++ ++ return ERROR_OK; + } + + COMMAND_HANDLER(handle_jtag_init_command) +@@ -921,8 +912,9 @@ static const struct command_registration jtag_subcommand_handlers[] = { + { + .name = "names", + .mode = COMMAND_ANY, +- .jim_handler = jim_jtag_names, ++ .handler = handle_jtag_names, + .help = "Returns list of all JTAG tap names.", ++ .usage = "", + }, + { + .chain = jtag_command_handlers_to_move, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0114-jtag-rewrite-command-jtag-arp_init-as-COMMAND_HANDLE.patch b/meta-oe/recipes-devtools/openocd/openocd/0114-jtag-rewrite-command-jtag-arp_init-as-COMMAND_HANDLE.patch new file mode 100644 index 000000000..3751e9379 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0114-jtag-rewrite-command-jtag-arp_init-as-COMMAND_HANDLE.patch @@ -0,0 +1,60 @@ +From ff0fdcf61427b76f1cfc9c3ecd551f058c0957d0 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 18:18:48 +0100 +Subject: [PATCH] jtag: rewrite command 'jtag arp_init' as COMMAND_HANDLER + +While there add the mandatory 'usage' field. + +Change-Id: I3491ed79d11c5a3e81cc9afd2423da14b8df72ff +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7495 +Tested-by: jenkins +--- + src/jtag/tcl.c | 23 +++++++---------------- + 1 file changed, 7 insertions(+), 16 deletions(-) + +diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c +index 83cb0a18b..f154295dd 100644 +--- a/src/jtag/tcl.c ++++ b/src/jtag/tcl.c +@@ -664,22 +664,12 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e) + } + } + +-static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_jtag_arp_init) + { +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc-1, argv + 1); +- if (goi.argc != 0) { +- Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); +- return JIM_ERR; +- } +- struct command_context *context = current_command_context(interp); +- int e = jtag_init_inner(context); +- if (e != ERROR_OK) { +- Jim_Obj *obj = Jim_NewIntObj(goi.interp, e); +- Jim_SetResultFormatted(goi.interp, "error: %#s", obj); +- return JIM_ERR; +- } +- return JIM_OK; ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ return jtag_init_inner(CMD_CTX); + } + + static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +@@ -843,10 +833,11 @@ static const struct command_registration jtag_subcommand_handlers[] = { + { + .name = "arp_init", + .mode = COMMAND_ANY, +- .jim_handler = jim_jtag_arp_init, ++ .handler = handle_jtag_arp_init, + .help = "Validates JTAG scan chain against the list of " + "declared TAPs using just the four standard JTAG " + "signals.", ++ .usage = "", + }, + { + .name = "arp_init-reset", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0115-jtag-rewrite-command-jtag-arp_init-reset-as-COMMAND_.patch b/meta-oe/recipes-devtools/openocd/openocd/0115-jtag-rewrite-command-jtag-arp_init-reset-as-COMMAND_.patch new file mode 100644 index 000000000..bb98ef3aa --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0115-jtag-rewrite-command-jtag-arp_init-reset-as-COMMAND_.patch @@ -0,0 +1,70 @@ +From 254598ba25265b79bac4a5e32fa2abb5d252d2cb Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 18:23:11 +0100 +Subject: [PATCH] jtag: rewrite command 'jtag arp_init-reset' as + COMMAND_HANDLER + +While there add the mandatory 'usage' field. + +Change-Id: I316fb31e24e94985dcc724e428b0384be7ef5bdd +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7496 +Tested-by: jenkins +--- + src/jtag/tcl.c | 32 ++++++++++++-------------------- + 1 file changed, 12 insertions(+), 20 deletions(-) + +diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c +index f154295dd..c6ca04810 100644 +--- a/src/jtag/tcl.c ++++ b/src/jtag/tcl.c +@@ -672,27 +672,18 @@ COMMAND_HANDLER(handle_jtag_arp_init) + return jtag_init_inner(CMD_CTX); + } + +-static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_jtag_arp_init_reset) + { +- int e = ERROR_OK; +- struct jim_getopt_info goi; +- jim_getopt_setup(&goi, interp, argc-1, argv + 1); +- if (goi.argc != 0) { +- Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); +- return JIM_ERR; +- } +- struct command_context *context = current_command_context(interp); ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ + if (transport_is_jtag()) +- e = jtag_init_reset(context); +- else if (transport_is_swd()) +- e = swd_init_reset(context); ++ return jtag_init_reset(CMD_CTX); + +- if (e != ERROR_OK) { +- Jim_Obj *obj = Jim_NewIntObj(goi.interp, e); +- Jim_SetResultFormatted(goi.interp, "error: %#s", obj); +- return JIM_ERR; +- } +- return JIM_OK; ++ if (transport_is_swd()) ++ return swd_init_reset(CMD_CTX); ++ ++ return ERROR_OK; + } + + int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +@@ -842,9 +833,10 @@ static const struct command_registration jtag_subcommand_handlers[] = { + { + .name = "arp_init-reset", + .mode = COMMAND_ANY, +- .jim_handler = jim_jtag_arp_init_reset, ++ .handler = handle_jtag_arp_init_reset, + .help = "Uses TRST and SRST to try resetting everything on " +- "the JTAG scan chain, then performs 'jtag arp_init'." ++ "the JTAG scan chain, then performs 'jtag arp_init'.", ++ .usage = "", + }, + { + .name = "newtap", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0116-jtag-rewrite-command-flush_count-as-COMMAND_HANDLER.patch b/meta-oe/recipes-devtools/openocd/openocd/0116-jtag-rewrite-command-flush_count-as-COMMAND_HANDLER.patch new file mode 100644 index 000000000..31cdf6b07 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0116-jtag-rewrite-command-flush_count-as-COMMAND_HANDLER.patch @@ -0,0 +1,53 @@ +From fbb7a50cbd5b9cda29698b3192e2a4596b3a6371 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 18:29:08 +0100 +Subject: [PATCH] jtag: rewrite command 'flush_count' as COMMAND_HANDLER + +While there: +- check the number of command parameters; +- add the mandatory 'usage' field. + +Change-Id: I7cd16f049753caedf19f313f7dc84be98efdba42 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7497 +Tested-by: jenkins +--- + src/jtag/tcl.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c +index c6ca04810..b3cbc48b4 100644 +--- a/src/jtag/tcl.c ++++ b/src/jtag/tcl.c +@@ -249,12 +249,15 @@ static int jim_command_pathmove(Jim_Interp *interp, int argc, Jim_Obj * const *a + return JIM_OK; + } + +- +-static int jim_command_flush_count(Jim_Interp *interp, int argc, Jim_Obj * const *args) ++COMMAND_HANDLER(handle_jtag_flush_count) + { +- Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count())); ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- return JIM_OK; ++ int count = jtag_get_flush_queue_count(); ++ command_print_sameline(CMD, "%d", count); ++ ++ return ERROR_OK; + } + + /* REVISIT Just what about these should "move" ... ? +@@ -279,9 +282,10 @@ static const struct command_registration jtag_command_handlers_to_move[] = { + { + .name = "flush_count", + .mode = COMMAND_EXEC, +- .jim_handler = jim_command_flush_count, ++ .handler = handle_jtag_flush_count, + .help = "Returns the number of times the JTAG queue " + "has been flushed.", ++ .usage = "", + }, + { + .name = "pathmove", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0117-target-arm_dap-rewrite-command-dap-names-as-COMMAND_.patch b/meta-oe/recipes-devtools/openocd/openocd/0117-target-arm_dap-rewrite-command-dap-names-as-COMMAND_.patch new file mode 100644 index 000000000..ec65ba397 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0117-target-arm_dap-rewrite-command-dap-names-as-COMMAND_.patch @@ -0,0 +1,58 @@ +From f76e67a440bb1761b90ea0cab89e0422a4224779 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 18:35:23 +0100 +Subject: [PATCH] target: arm_dap: rewrite command 'dap names' as + COMMAND_HANDLER + +While there, format in a human readable way the output list by +using one line per dap name. + +Change-Id: I24a47350105b90db15808c61790f05d807120739 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7498 +Tested-by: jenkins +--- + src/target/arm_dap.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c +index e21136dd6..bc9d96236 100644 +--- a/src/target/arm_dap.c ++++ b/src/target/arm_dap.c +@@ -421,20 +421,16 @@ static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) + return dap_create(&goi); + } + +-static int jim_dap_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_dap_names) + { ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ + struct arm_dap_object *obj; ++ list_for_each_entry(obj, &all_dap, lh) ++ command_print(CMD, "%s", obj->name); + +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } +- Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); +- list_for_each_entry(obj, &all_dap, lh) { +- Jim_ListAppendElement(interp, Jim_GetResult(interp), +- Jim_NewStringObj(interp, obj->name, -1)); +- } +- return JIM_OK; ++ return ERROR_OK; + } + + COMMAND_HANDLER(handle_dap_init) +@@ -500,7 +496,7 @@ static const struct command_registration dap_subcommand_handlers[] = { + { + .name = "names", + .mode = COMMAND_ANY, +- .jim_handler = jim_dap_names, ++ .handler = handle_dap_names, + .usage = "", + .help = "Lists all registered DAP instances by name", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0118-target-arm_tpiu_swo-rewrite-command-tpiu-disable-as-.patch b/meta-oe/recipes-devtools/openocd/openocd/0118-target-arm_tpiu_swo-rewrite-command-tpiu-disable-as-.patch new file mode 100644 index 000000000..d2c8dd6d6 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0118-target-arm_tpiu_swo-rewrite-command-tpiu-disable-as-.patch @@ -0,0 +1,76 @@ +From 8fa6db6e8e992793f5dcc23a7182e2b0cb70257e Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 20:28:56 +0100 +Subject: [PATCH] target: arm_tpiu_swo: rewrite command 'tpiu disable' as + COMMAND_HANDLER + +Change-Id: I689482f898bde2afa2881b2f311676a6b98abb9a +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7499 +Tested-by: jenkins +--- + src/target/arm_tpiu_swo.c | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c +index 7096db305..897a9316c 100644 +--- a/src/target/arm_tpiu_swo.c ++++ b/src/target/arm_tpiu_swo.c +@@ -820,18 +820,15 @@ error_exit: + return JIM_ERR; + } + +-static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_arm_tpiu_swo_disable) + { +- struct command *c = jim_to_command(interp); +- struct arm_tpiu_swo_object *obj = c->jim_handler_data; ++ struct arm_tpiu_swo_object *obj = CMD_DATA; + +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + + if (!obj->enabled) +- return JIM_OK; ++ return ERROR_OK; + obj->enabled = false; + + arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE); +@@ -845,20 +842,19 @@ static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const + + int retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL); + if (retval != ERROR_OK) { +- LOG_ERROR("Failed to stop adapter's trace"); +- return JIM_ERR; ++ command_print(CMD, "Failed to stop adapter's trace"); ++ return retval; + } + } + + arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE); + + /* START_DEPRECATED_TPIU */ +- struct command_context *cmd_ctx = current_command_context(interp); +- struct target *target = get_current_target(cmd_ctx); ++ struct target *target = get_current_target(CMD_CTX); + target_handle_event(target, TARGET_EVENT_TRACE_CONFIG); + /* END_DEPRECATED_TPIU */ + +- return JIM_OK; ++ return ERROR_OK; + } + + static const struct command_registration arm_tpiu_swo_instance_command_handlers[] = { +@@ -893,7 +889,7 @@ static const struct command_registration arm_tpiu_swo_instance_command_handlers[ + { + .name = "disable", + .mode = COMMAND_EXEC, +- .jim_handler = jim_arm_tpiu_swo_disable, ++ .handler = handle_arm_tpiu_swo_disable, + .usage = "", + .help = "Disables the TPIU/SWO output", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0119-target-arm_tpiu_swo-rewrite-command-tpiu-enable-as-C.patch b/meta-oe/recipes-devtools/openocd/openocd/0119-target-arm_tpiu_swo-rewrite-command-tpiu-enable-as-C.patch new file mode 100644 index 000000000..fe055d512 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0119-target-arm_tpiu_swo-rewrite-command-tpiu-enable-as-C.patch @@ -0,0 +1,233 @@ +From 5d39a8852ab604bed29d9e0d28da2cb5f7a87958 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 20:52:51 +0100 +Subject: [PATCH] target: arm_tpiu_swo: rewrite command 'tpiu enable' as + COMMAND_HANDLER + +Change-Id: Ia600948b99a229ef0490b7f576df62f880db8546 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7500 +Tested-by: jenkins +--- + src/target/arm_tpiu_swo.c | 94 +++++++++++++++++++-------------------- + 1 file changed, 45 insertions(+), 49 deletions(-) + +diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c +index 897a9316c..3cf306377 100644 +--- a/src/target/arm_tpiu_swo.c ++++ b/src/target/arm_tpiu_swo.c +@@ -595,54 +595,52 @@ static const struct service_driver arm_tpiu_swo_service_driver = { + .keep_client_alive_handler = NULL, + }; + +-static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_arm_tpiu_swo_enable) + { +- struct command *c = jim_to_command(interp); +- struct arm_tpiu_swo_object *obj = c->jim_handler_data; +- struct command_context *cmd_ctx = current_command_context(interp); ++ struct arm_tpiu_swo_object *obj = CMD_DATA; + uint32_t value; + int retval; + +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- if (cmd_ctx->mode == COMMAND_CONFIG) { ++ if (CMD_CTX->mode == COMMAND_CONFIG) { + LOG_DEBUG("%s: enable deferred", obj->name); + obj->deferred_enable = true; +- return JIM_OK; ++ return ERROR_OK; + } + + if (obj->enabled) +- return JIM_OK; ++ return ERROR_OK; + + if (transport_is_hla() && obj->spot.ap_num != 0) { +- LOG_ERROR("Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", obj->spot.ap_num); +- return JIM_ERR; ++ command_print(CMD, ++ "Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", ++ obj->spot.ap_num); ++ return ERROR_FAIL; + } + + if (!obj->traceclkin_freq) { +- LOG_ERROR("Trace clock-in frequency not set"); +- return JIM_ERR; ++ command_print(CMD, "Trace clock-in frequency not set"); ++ return ERROR_FAIL; + } + + if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) + if (!obj->swo_pin_freq) + LOG_DEBUG("SWO pin frequency not set, will be autodetected by the adapter"); + +- struct target *target = get_current_target(cmd_ctx); ++ struct target *target = get_current_target(CMD_CTX); + + /* START_DEPRECATED_TPIU */ + if (obj->recheck_ap_cur_target) { + if (strcmp(target->type->name, "cortex_m") && + strcmp(target->type->name, "hla_target")) { + LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA"); +- return JIM_ERR; ++ return ERROR_FAIL; + } + if (!target_was_examined(target)) { + LOG_ERROR(MSG "Current target not examined yet"); +- return JIM_ERR; ++ return ERROR_FAIL; + } + struct cortex_m_common *cm = target_to_cm(target); + obj->recheck_ap_cur_target = false; +@@ -660,8 +658,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const + if (!obj->ap) { + obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num); + if (!obj->ap) { +- LOG_ERROR("Cannot get AP"); +- return JIM_ERR; ++ command_print(CMD, "Cannot get AP"); ++ return ERROR_FAIL; + } + } + +@@ -670,8 +668,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const + + retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value); + if (retval != ERROR_OK) { +- LOG_ERROR("Unable to read %s", obj->name); +- return JIM_ERR; ++ command_print(CMD, "Unable to read %s", obj->name); ++ return retval; + } + switch (obj->pin_protocol) { + case TPIU_SPPR_PROTOCOL_SYNC: +@@ -687,21 +685,20 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const + value = 0; + } + if (!value) { +- struct jim_nvp *p; +- jim_nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p); +- LOG_ERROR("%s does not support protocol %s", obj->name, p->name); +- return JIM_ERR; ++ struct jim_nvp *p = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol); ++ command_print(CMD, "%s does not support protocol %s", obj->name, p->name); ++ return ERROR_FAIL; + } + + if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) { + retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value); + if (retval != ERROR_OK) { +- LOG_ERROR("Cannot read TPIU register SSPSR"); +- return JIM_ERR; ++ command_print(CMD, "Cannot read TPIU register SSPSR"); ++ return retval; + } + if (!(value & BIT(obj->port_width - 1))) { +- LOG_ERROR("TPIU does not support port-width of %d bits", obj->port_width); +- return JIM_ERR; ++ command_print(CMD, "TPIU does not support port-width of %d bits", obj->port_width); ++ return ERROR_FAIL; + } + } + +@@ -713,41 +710,42 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const + struct arm_tpiu_swo_priv_connection *priv = malloc(sizeof(*priv)); + if (!priv) { + LOG_ERROR("Out of memory"); +- return JIM_ERR; ++ return ERROR_FAIL; + } + priv->obj = obj; + LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]); + retval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1], + CONNECTION_LIMIT_UNLIMITED, priv); + if (retval != ERROR_OK) { +- LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]); +- return JIM_ERR; ++ command_print(CMD, "Can't configure trace TCP port %s", &obj->out_filename[1]); ++ return retval; + } + } else if (strcmp(obj->out_filename, "-")) { + obj->file = fopen(obj->out_filename, "ab"); + if (!obj->file) { +- LOG_ERROR("Can't open trace destination file \"%s\"", obj->out_filename); +- return JIM_ERR; ++ command_print(CMD, "Can't open trace destination file \"%s\"", obj->out_filename); ++ return ERROR_FAIL; + } + } + + retval = adapter_config_trace(true, obj->pin_protocol, obj->port_width, + &swo_pin_freq, obj->traceclkin_freq, &prescaler); + if (retval != ERROR_OK) { +- LOG_ERROR("Failed to start adapter's trace"); ++ command_print(CMD, "Failed to start adapter's trace"); + arm_tpiu_swo_close_output(obj); +- return JIM_ERR; ++ return retval; + } + + if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) + if (!swo_pin_freq) { + if (obj->swo_pin_freq) +- LOG_ERROR("Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq); ++ command_print(CMD, "Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq); + else +- LOG_ERROR("Adapter does not support auto-detection of SWO pin frequency nor a default value"); ++ command_print(CMD, ++ "Adapter does not support auto-detection of SWO pin frequency nor a default value"); + + arm_tpiu_swo_close_output(obj); +- return JIM_ERR; ++ return ERROR_FAIL; + } + + if (obj->swo_pin_freq != swo_pin_freq) +@@ -799,10 +797,10 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const + /* END_DEPRECATED_TPIU */ + + obj->enabled = true; +- return JIM_OK; ++ return ERROR_OK; + + error_exit: +- LOG_ERROR("Error!"); ++ command_print(CMD, "Error!"); + + if (obj->en_capture) { + obj->en_capture = false; +@@ -811,13 +809,11 @@ error_exit: + + target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj); + +- retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL); +- if (retval != ERROR_OK) { +- LOG_ERROR("Failed to stop adapter's trace"); +- return JIM_ERR; +- } ++ int retval1 = adapter_config_trace(false, 0, 0, NULL, 0, NULL); ++ if (retval1 != ERROR_OK) ++ command_print(CMD, "Failed to stop adapter's trace"); + } +- return JIM_ERR; ++ return retval; + } + + COMMAND_HANDLER(handle_arm_tpiu_swo_disable) +@@ -882,7 +878,7 @@ static const struct command_registration arm_tpiu_swo_instance_command_handlers[ + { + .name = "enable", + .mode = COMMAND_ANY, +- .jim_handler = jim_arm_tpiu_swo_enable, ++ .handler = handle_arm_tpiu_swo_enable, + .usage = "", + .help = "Enables the TPIU/SWO output", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0120-target-arm_tpiu_swo-rewrite-command-tpiu-names-as-CO.patch b/meta-oe/recipes-devtools/openocd/openocd/0120-target-arm_tpiu_swo-rewrite-command-tpiu-names-as-CO.patch new file mode 100644 index 000000000..1d52b6807 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0120-target-arm_tpiu_swo-rewrite-command-tpiu-names-as-CO.patch @@ -0,0 +1,59 @@ +From 90ddac12e38ab21b1d3934235e0d1242e0f13616 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 20:56:40 +0100 +Subject: [PATCH] target: arm_tpiu_swo: rewrite command 'tpiu names' as + COMMAND_HANDLER + +While there, format in a human readable way the output list by +using one line per tpiu name. + +Change-Id: I937c92b6c1e92509cf8aa96be1517a51bc363600 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7501 +Tested-by: jenkins +--- + src/target/arm_tpiu_swo.c | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c +index 3cf306377..55201e6fe 100644 +--- a/src/target/arm_tpiu_swo.c ++++ b/src/target/arm_tpiu_swo.c +@@ -981,20 +981,17 @@ err_exit: + return JIM_ERR; + } + +-static int jim_arm_tpiu_swo_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_arm_tpiu_swo_names) + { + struct arm_tpiu_swo_object *obj; + +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } +- Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); +- list_for_each_entry(obj, &all_tpiu_swo, lh) { +- Jim_ListAppendElement(interp, Jim_GetResult(interp), +- Jim_NewStringObj(interp, obj->name, -1)); +- } +- return JIM_OK; ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ list_for_each_entry(obj, &all_tpiu_swo, lh) ++ command_print(CMD, "%s", obj->name); ++ ++ return ERROR_OK; + } + + static int jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +@@ -1185,7 +1182,7 @@ static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = { + { + .name = "names", + .mode = COMMAND_ANY, +- .jim_handler = jim_arm_tpiu_swo_names, ++ .handler = handle_arm_tpiu_swo_names, + .usage = "", + .help = "Lists all registered TPIU and SWO objects by name", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0121-target-arm_tpiu_swo-rewrite-command-tpiu-init-as-COM.patch b/meta-oe/recipes-devtools/openocd/openocd/0121-target-arm_tpiu_swo-rewrite-command-tpiu-init-as-COM.patch new file mode 100644 index 000000000..567f25626 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0121-target-arm_tpiu_swo-rewrite-command-tpiu-init-as-COM.patch @@ -0,0 +1,58 @@ +From 6f8c27dcfc51c3775f11785711d44563adb6eb17 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 21:00:42 +0100 +Subject: [PATCH] target: arm_tpiu_swo: rewrite command 'tpiu init' as + COMMAND_HANDLER + +Change-Id: Iaaccfc62dd85267066a152c434f254d1b9a0c4f1 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7502 +Tested-by: jenkins +--- + src/target/arm_tpiu_swo.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c +index 55201e6fe..5cea682ec 100644 +--- a/src/target/arm_tpiu_swo.c ++++ b/src/target/arm_tpiu_swo.c +@@ -994,23 +994,21 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_names) + return ERROR_OK; + } + +-static int jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_arm_tpiu_swo_init) + { +- struct command_context *cmd_ctx = current_command_context(interp); + struct arm_tpiu_swo_object *obj; +- int retval = JIM_OK; ++ int retval = ERROR_OK; ++ ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } + list_for_each_entry(obj, &all_tpiu_swo, lh) { + if (!obj->deferred_enable) + continue; + LOG_DEBUG("%s: running enable during init", obj->name); +- int retval2 = command_run_linef(cmd_ctx, "%s enable", obj->name); ++ int retval2 = command_run_linef(CMD_CTX, "%s enable", obj->name); + if (retval2 != ERROR_OK) +- retval = JIM_ERR; ++ retval = retval2; + } + return retval; + } +@@ -1189,7 +1187,7 @@ static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = { + { + .name = "init", + .mode = COMMAND_EXEC, +- .jim_handler = jim_arm_tpiu_swo_init, ++ .handler = handle_arm_tpiu_swo_init, + .usage = "", + .help = "Initialize TPIU and SWO", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0122-target-rewrite-command-read_memory-as-COMMAND_HANDLE.patch b/meta-oe/recipes-devtools/openocd/openocd/0122-target-rewrite-command-read_memory-as-COMMAND_HANDLE.patch new file mode 100644 index 000000000..f55c6692e --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0122-target-rewrite-command-read_memory-as-COMMAND_HANDLE.patch @@ -0,0 +1,212 @@ +From 584986ab1c9902fb58d928c1cb4ae885989fecbf Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 23:15:54 +0100 +Subject: [PATCH] target: rewrite command 'read_memory' as COMMAND_HANDLER + +While there, fix typo on 'exceeds'. +In a following patch, the output could be formatted and split in N +values per line to make it easier to read by humans. + +Change-Id: I295111a80934393011e46311f6cf6c13f2bdc0a3 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7503 +Tested-by: jenkins +--- + src/target/target.c | 110 ++++++++++++++++---------------------------- + 1 file changed, 39 insertions(+), 71 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index ae419ac8b..07c3c29a4 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -4592,57 +4592,36 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, + return e; + } + +-static int target_jim_read_memory(Jim_Interp *interp, int argc, +- Jim_Obj * const *argv) ++COMMAND_HANDLER(handle_target_read_memory) + { + /* +- * argv[1] = memory address +- * argv[2] = desired element width in bits +- * argv[3] = number of elements to read +- * argv[4] = optional "phys" ++ * CMD_ARGV[0] = memory address ++ * CMD_ARGV[1] = desired element width in bits ++ * CMD_ARGV[2] = number of elements to read ++ * CMD_ARGV[3] = optional "phys" + */ + +- if (argc < 4 || argc > 5) { +- Jim_WrongNumArgs(interp, 1, argv, "address width count ['phys']"); +- return JIM_ERR; +- } ++ if (CMD_ARGC < 3 || CMD_ARGC > 4) ++ return ERROR_COMMAND_SYNTAX_ERROR; + + /* Arg 1: Memory address. */ +- jim_wide wide_addr; +- int e; +- e = Jim_GetWide(interp, argv[1], &wide_addr); +- +- if (e != JIM_OK) +- return e; +- +- target_addr_t addr = (target_addr_t)wide_addr; ++ target_addr_t addr; ++ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], addr); + + /* Arg 2: Bit width of one element. */ +- long l; +- e = Jim_GetLong(interp, argv[2], &l); +- +- if (e != JIM_OK) +- return e; +- +- const unsigned int width_bits = l; ++ unsigned int width_bits; ++ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], width_bits); + + /* Arg 3: Number of elements to read. */ +- e = Jim_GetLong(interp, argv[3], &l); +- +- if (e != JIM_OK) +- return e; +- +- size_t count = l; ++ unsigned int count; ++ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], count); + + /* Arg 4: Optional 'phys'. */ + bool is_phys = false; +- +- if (argc > 4) { +- const char *phys = Jim_GetString(argv[4], NULL); +- +- if (strcmp(phys, "phys")) { +- Jim_SetResultFormatted(interp, "invalid argument '%s', must be 'phys'", phys); +- return JIM_ERR; ++ if (CMD_ARGC == 4) { ++ if (strcmp(CMD_ARGV[3], "phys")) { ++ command_print(CMD, "invalid argument '%s', must be 'phys'", CMD_ARGV[3]); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + + is_phys = true; +@@ -4655,37 +4634,33 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, + case 64: + break; + default: +- Jim_SetResultString(interp, "invalid width, must be 8, 16, 32 or 64", -1); +- return JIM_ERR; ++ command_print(CMD, "invalid width, must be 8, 16, 32 or 64"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + + const unsigned int width = width_bits / 8; + + if ((addr + (count * width)) < addr) { +- Jim_SetResultString(interp, "read_memory: addr + count wraps to zero", -1); +- return JIM_ERR; ++ command_print(CMD, "read_memory: addr + count wraps to zero"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + + if (count > 65536) { +- Jim_SetResultString(interp, "read_memory: too large read request, exeeds 64K elements", -1); +- return JIM_ERR; ++ command_print(CMD, "read_memory: too large read request, exceeds 64K elements"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; + } + +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx != NULL); +- struct target *target = get_current_target(cmd_ctx); ++ struct target *target = get_current_target(CMD_CTX); + + const size_t buffersize = 4096; + uint8_t *buffer = malloc(buffersize); + + if (!buffer) { + LOG_ERROR("Failed to allocate memory"); +- return JIM_ERR; ++ return ERROR_FAIL; + } + +- Jim_Obj *result_list = Jim_NewListObj(interp, NULL, 0); +- Jim_IncrRefCount(result_list); +- ++ char *separator = ""; + while (count > 0) { + const unsigned int max_chunk_len = buffersize / width; + const size_t chunk_len = MIN(count, max_chunk_len); +@@ -4698,11 +4673,15 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, + retval = target_read_memory(target, addr, width, chunk_len, buffer); + + if (retval != ERROR_OK) { +- LOG_ERROR("read_memory: read at " TARGET_ADDR_FMT " with width=%u and count=%zu failed", ++ LOG_DEBUG("read_memory: read at " TARGET_ADDR_FMT " with width=%u and count=%zu failed", + addr, width_bits, chunk_len); +- Jim_SetResultString(interp, "read_memory: failed to read memory", -1); +- e = JIM_ERR; +- break; ++ /* ++ * FIXME: we append the errmsg to the list of value already read. ++ * Add a way to flush and replace old output, but LOG_DEBUG() it ++ */ ++ command_print(CMD, "read_memory: failed to read memory"); ++ free(buffer); ++ return retval; + } + + for (size_t i = 0; i < chunk_len ; i++) { +@@ -4723,11 +4702,8 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, + break; + } + +- char value_buf[19]; +- snprintf(value_buf, sizeof(value_buf), "0x%" PRIx64, v); +- +- Jim_ListAppendElement(interp, result_list, +- Jim_NewStringObj(interp, value_buf, -1)); ++ command_print_sameline(CMD, "%s0x%" PRIx64, separator, v); ++ separator = " "; + } + + count -= chunk_len; +@@ -4736,15 +4712,7 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, + + free(buffer); + +- if (e != JIM_OK) { +- Jim_DecrRefCount(interp, result_list); +- return e; +- } +- +- Jim_SetResult(interp, result_list); +- Jim_DecrRefCount(interp, result_list); +- +- return JIM_OK; ++ return ERROR_OK; + } + + static int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t idx, uint64_t *val) +@@ -6074,7 +6042,7 @@ static const struct command_registration target_instance_command_handlers[] = { + { + .name = "read_memory", + .mode = COMMAND_EXEC, +- .jim_handler = target_jim_read_memory, ++ .handler = handle_target_read_memory, + .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory", + .usage = "address width count ['phys']", + }, +@@ -7203,7 +7171,7 @@ static const struct command_registration target_exec_command_handlers[] = { + { + .name = "read_memory", + .mode = COMMAND_EXEC, +- .jim_handler = target_jim_read_memory, ++ .handler = handle_target_read_memory, + .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory", + .usage = "address width count ['phys']", + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0123-target-rewrite-command-target-curstate-as-COMMAND_HA.patch b/meta-oe/recipes-devtools/openocd/openocd/0123-target-rewrite-command-target-curstate-as-COMMAND_HA.patch new file mode 100644 index 000000000..abe112911 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0123-target-rewrite-command-target-curstate-as-COMMAND_HA.patch @@ -0,0 +1,60 @@ +From 113ba58231683e8cba329bf83b96d2192c39ad93 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 23:25:21 +0100 +Subject: [PATCH] target: rewrite command 'target curstate' as COMMAND_HANDLER + +While there, add the mandatory 'usage' field. + +Change-Id: Ibfda6f56a1450e2eb9ad3092d756de0778f4a092 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7504 +Tested-by: jenkins +--- + src/target/target.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index 07c3c29a4..da9cab904 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -5904,18 +5904,19 @@ COMMAND_HANDLER(handle_target_event_list) + command_print(CMD, "***END***"); + return ERROR_OK; + } +-static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++ ++COMMAND_HANDLER(handle_target_current_state) + { +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "[no parameters]"); +- return JIM_ERR; +- } +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); +- Jim_SetResultString(interp, target_state_name(target), -1); +- return JIM_OK; ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ struct target *target = get_current_target(CMD_CTX); ++ ++ command_print(CMD, "%s", target_state_name(target)); ++ ++ return ERROR_OK; + } ++ + static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv) + { + struct jim_getopt_info goi; +@@ -6063,8 +6064,9 @@ static const struct command_registration target_instance_command_handlers[] = { + { + .name = "curstate", + .mode = COMMAND_EXEC, +- .jim_handler = jim_target_current_state, ++ .handler = handle_target_current_state, + .help = "displays the current state of this target", ++ .usage = "", + }, + { + .name = "arp_examine", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0124-target-rewrite-command-was_examined-as-COMMAND_HANDL.patch b/meta-oe/recipes-devtools/openocd/openocd/0124-target-rewrite-command-was_examined-as-COMMAND_HANDL.patch new file mode 100644 index 000000000..1ed08e529 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0124-target-rewrite-command-was_examined-as-COMMAND_HANDL.patch @@ -0,0 +1,53 @@ +From cca64798f8f01f2f06dbc020113cf9497b56f68b Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 23:37:07 +0100 +Subject: [PATCH] target: rewrite command 'was_examined' as COMMAND_HANDLER + +Check for empty command line, add the mandatory 'usage' field. + +Change-Id: I3f59448458fe01268bf5f4293aea5adcbd6d8279 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7505 +Tested-by: jenkins +--- + src/target/target.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index da9cab904..264b85f21 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -5716,14 +5716,16 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv + return JIM_OK; + } + +-static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(handle_target_was_examined) + { +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- Jim_SetResultBool(interp, target_was_examined(target)); +- return JIM_OK; ++ struct target *target = get_current_target(CMD_CTX); ++ ++ command_print(CMD, "%d", target_was_examined(target) ? 1 : 0); ++ ++ return ERROR_OK; + } + + static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +@@ -6078,8 +6080,9 @@ static const struct command_registration target_instance_command_handlers[] = { + { + .name = "was_examined", + .mode = COMMAND_EXEC, +- .jim_handler = jim_target_was_examined, ++ .handler = handle_target_was_examined, + .help = "used internally for reset processing", ++ .usage = "", + }, + { + .name = "examine_deferred", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0125-target-rewrite-command-examine_deferred-as-COMMAND_H.patch b/meta-oe/recipes-devtools/openocd/openocd/0125-target-rewrite-command-examine_deferred-as-COMMAND_H.patch new file mode 100644 index 000000000..6a38d078f --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0125-target-rewrite-command-examine_deferred-as-COMMAND_H.patch @@ -0,0 +1,53 @@ +From 2dda0e37d91f3ba9345dc20253ac162ff449504d Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 23:41:22 +0100 +Subject: [PATCH] target: rewrite command 'examine_deferred' as COMMAND_HANDLER + +Check for empty command line, add the mandatory 'usage' field. + +Change-Id: I9c3606242ec3dda9026fe19222162a110e618bff +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7506 +Tested-by: jenkins +--- + src/target/target.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index 264b85f21..a2c857a95 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -5728,14 +5728,16 @@ COMMAND_HANDLER(handle_target_was_examined) + return ERROR_OK; + } + +-static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv) ++COMMAND_HANDLER(handle_target_examine_deferred) + { +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- Jim_SetResultBool(interp, target->defer_examine); +- return JIM_OK; ++ struct target *target = get_current_target(CMD_CTX); ++ ++ command_print(CMD, "%d", target->defer_examine ? 1 : 0); ++ ++ return ERROR_OK; + } + + static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +@@ -6087,8 +6089,9 @@ static const struct command_registration target_instance_command_handlers[] = { + { + .name = "examine_deferred", + .mode = COMMAND_EXEC, +- .jim_handler = jim_target_examine_deferred, ++ .handler = handle_target_examine_deferred, + .help = "used internally for reset processing", ++ .usage = "", + }, + { + .name = "arp_halt_gdb", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0126-target-rewrite-command-arp_halt_gdb-as-COMMAND_HANDL.patch b/meta-oe/recipes-devtools/openocd/openocd/0126-target-rewrite-command-arp_halt_gdb-as-COMMAND_HANDL.patch new file mode 100644 index 000000000..300f784d6 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0126-target-rewrite-command-arp_halt_gdb-as-COMMAND_HANDL.patch @@ -0,0 +1,56 @@ +From 583efa68f71b9ad8e06b8e1246af25fc6c70e052 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 23:44:04 +0100 +Subject: [PATCH] target: rewrite command 'arp_halt_gdb' as COMMAND_HANDLER + +While there add the mandatory 'usage' field. + +Change-Id: I5389881dac25877dc32930ec36ee546e48ecc14d +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7507 +Tested-by: jenkins +--- + src/target/target.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index a2c857a95..4e2914648 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -5740,20 +5740,14 @@ COMMAND_HANDLER(handle_target_examine_deferred) + return ERROR_OK; + } + +-static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_target_halt_gdb) + { +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "[no parameters]"); +- return JIM_ERR; +- } +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); +- struct target *target = get_current_target(cmd_ctx); ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK) +- return JIM_ERR; ++ struct target *target = get_current_target(CMD_CTX); + +- return JIM_OK; ++ return target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); + } + + static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +@@ -6096,8 +6090,9 @@ static const struct command_registration target_instance_command_handlers[] = { + { + .name = "arp_halt_gdb", + .mode = COMMAND_EXEC, +- .jim_handler = jim_target_halt_gdb, ++ .handler = handle_target_halt_gdb, + .help = "used internally for reset processing to halt GDB", ++ .usage = "", + }, + { + .name = "arp_poll", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0127-target-rewrite-command-target-current-as-COMMAND_HAN.patch b/meta-oe/recipes-devtools/openocd/openocd/0127-target-rewrite-command-target-current-as-COMMAND_HAN.patch new file mode 100644 index 000000000..8d8079145 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0127-target-rewrite-command-target-current-as-COMMAND_HAN.patch @@ -0,0 +1,57 @@ +From 26f457896c456c57a57719e484d055d444ba67ee Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 23:50:23 +0100 +Subject: [PATCH] target: rewrite command 'target current' as COMMAND_HANDLER + +While there add the mandatory 'usage' field. + +Change-Id: I3e5b826ca58f7ade30a443ada0cb4a9cd9ea35c2 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7508 +Tested-by: jenkins +--- + src/target/target.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index 4e2914648..ae5f74cbf 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -6365,19 +6365,16 @@ static int target_create(struct jim_getopt_info *goi) + return JIM_OK; + } + +-static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_target_current) + { +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } +- struct command_context *cmd_ctx = current_command_context(interp); +- assert(cmd_ctx); ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; + +- struct target *target = get_current_target_or_null(cmd_ctx); ++ struct target *target = get_current_target_or_null(CMD_CTX); + if (target) +- Jim_SetResultString(interp, target_name(target), -1); +- return JIM_OK; ++ command_print(CMD, "%s", target_name(target)); ++ ++ return ERROR_OK; + } + + static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +@@ -6522,8 +6519,9 @@ static const struct command_registration target_subcommand_handlers[] = { + { + .name = "current", + .mode = COMMAND_ANY, +- .jim_handler = jim_target_current, ++ .handler = handle_target_current, + .help = "Returns the currently selected target", ++ .usage = "", + }, + { + .name = "types", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0128-target-rewrite-command-target-types-as-COMMAND_HANDL.patch b/meta-oe/recipes-devtools/openocd/openocd/0128-target-rewrite-command-target-types-as-COMMAND_HANDL.patch new file mode 100644 index 000000000..5bb740471 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0128-target-rewrite-command-target-types-as-COMMAND_HANDL.patch @@ -0,0 +1,59 @@ +From d9d698103e974b2a94c611864cccb92359509b7d Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 23:54:10 +0100 +Subject: [PATCH] target: rewrite command 'target types' as COMMAND_HANDLER + +Print one entry per line. +While there add the mandatory 'usage' field. + +Change-Id: I135556e12154e33fdbd0f71d89f6fe37c69813b7 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7509 +Tested-by: jenkins +--- + src/target/target.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index ae5f74cbf..b77a25a2a 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -6377,18 +6377,15 @@ COMMAND_HANDLER(handle_target_current) + return ERROR_OK; + } + +-static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_target_types) + { +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } +- Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); +- for (unsigned x = 0; target_types[x]; x++) { +- Jim_ListAppendElement(interp, Jim_GetResult(interp), +- Jim_NewStringObj(interp, target_types[x]->name, -1)); +- } +- return JIM_OK; ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ for (unsigned int x = 0; target_types[x]; x++) ++ command_print(CMD, "%s", target_types[x]->name); ++ ++ return ERROR_OK; + } + + static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +@@ -6526,9 +6523,10 @@ static const struct command_registration target_subcommand_handlers[] = { + { + .name = "types", + .mode = COMMAND_ANY, +- .jim_handler = jim_target_types, ++ .handler = handle_target_types, + .help = "Returns the available target types as " + "a list of strings", ++ .usage = "", + }, + { + .name = "names", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0129-target-rewrite-command-target-names-as-COMMAND_HANDL.patch b/meta-oe/recipes-devtools/openocd/openocd/0129-target-rewrite-command-target-names-as-COMMAND_HANDL.patch new file mode 100644 index 000000000..c1d4e79c8 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0129-target-rewrite-command-target-names-as-COMMAND_HANDL.patch @@ -0,0 +1,59 @@ +From 12b405a4ac3dddd18e2fd822e135bb783cae0236 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Mon, 19 Dec 2022 23:58:01 +0100 +Subject: [PATCH] target: rewrite command 'target names' as COMMAND_HANDLER + +Print one entry per line. +While there add the mandatory 'usage' field. + +Change-Id: Ia832684817f3bdbfa4cb943cd97e3f9fb2605902 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7510 +Tested-by: jenkins +--- + src/target/target.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index b77a25a2a..3fdb34ec6 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -6388,20 +6388,18 @@ COMMAND_HANDLER(handle_target_types) + return ERROR_OK; + } + +-static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_target_names) + { +- if (argc != 1) { +- Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); +- return JIM_ERR; +- } +- Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); ++ if (CMD_ARGC != 0) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ + struct target *target = all_targets; + while (target) { +- Jim_ListAppendElement(interp, Jim_GetResult(interp), +- Jim_NewStringObj(interp, target_name(target), -1)); ++ command_print(CMD, "%s", target_name(target)); + target = target->next; + } +- return JIM_OK; ++ ++ return ERROR_OK; + } + + static struct target_list * +@@ -6531,8 +6529,9 @@ static const struct command_registration target_subcommand_handlers[] = { + { + .name = "names", + .mode = COMMAND_ANY, +- .jim_handler = jim_target_names, ++ .handler = handle_target_names, + .help = "Returns the names of all targets as a list of strings", ++ .usage = "", + }, + { + .name = "smp", diff --git a/meta-oe/recipes-devtools/openocd/openocd/0130-target-rewrite-command-target-smp-as-COMMAND_HANDLER.patch b/meta-oe/recipes-devtools/openocd/openocd/0130-target-rewrite-command-target-smp-as-COMMAND_HANDLER.patch new file mode 100644 index 000000000..2da792f20 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0130-target-rewrite-command-target-smp-as-COMMAND_HANDLER.patch @@ -0,0 +1,121 @@ +From e9a7221b68d0775d9c96c8a12a7a26e2729caf37 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Tue, 20 Dec 2022 00:11:41 +0100 +Subject: [PATCH] target: rewrite command 'target smp' as COMMAND_HANDLER + +This also fixes an incorrect return ERROR_xx from a jim command, +propagated from return value of rtos_smp_init(). + +Change-Id: Icf4893c00aabd8fadd60077c5e8a2e926f687518 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7511 +Tested-by: jenkins +--- + src/target/target.c | 41 ++++++++++++++++++++--------------------- + 1 file changed, 20 insertions(+), 21 deletions(-) + +diff --git a/src/target/target.c b/src/target/target.c +index 3fdb34ec6..47abd2823 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -6404,9 +6404,8 @@ COMMAND_HANDLER(handle_target_names) + + static struct target_list * + __attribute__((warn_unused_result)) +-create_target_list_node(Jim_Obj *const name) { +- int len; +- const char *targetname = Jim_GetString(name, &len); ++create_target_list_node(const char *targetname) ++{ + struct target *target = get_target(targetname); + LOG_DEBUG("%s ", targetname); + if (!target) +@@ -6422,7 +6421,8 @@ create_target_list_node(Jim_Obj *const name) { + return new; + } + +-static int get_target_with_common_rtos_type(struct list_head *lh, struct target **result) ++static int get_target_with_common_rtos_type(struct command_invocation *cmd, ++ struct list_head *lh, struct target **result) + { + struct target *target = NULL; + struct target_list *curr; +@@ -6430,39 +6430,39 @@ static int get_target_with_common_rtos_type(struct list_head *lh, struct target + struct rtos *curr_rtos = curr->target->rtos; + if (curr_rtos) { + if (target && target->rtos && target->rtos->type != curr_rtos->type) { +- LOG_ERROR("Different rtos types in members of one smp target!"); +- return JIM_ERR; ++ command_print(cmd, "Different rtos types in members of one smp target!"); ++ return ERROR_FAIL; + } + target = curr->target; + } + } + *result = target; +- return JIM_OK; ++ return ERROR_OK; + } + +-static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) ++COMMAND_HANDLER(handle_target_smp) + { + static int smp_group = 1; + +- if (argc == 1) { ++ if (CMD_ARGC == 0) { + LOG_DEBUG("Empty SMP target"); +- return JIM_OK; ++ return ERROR_OK; + } +- LOG_DEBUG("%d", argc); +- /* argv[1] = target to associate in smp +- * argv[2] = target to associate in smp +- * argv[3] ... ++ LOG_DEBUG("%d", CMD_ARGC); ++ /* CMD_ARGC[0] = target to associate in smp ++ * CMD_ARGC[1] = target to associate in smp ++ * CMD_ARGC[2] ... + */ + + struct list_head *lh = malloc(sizeof(*lh)); + if (!lh) { + LOG_ERROR("Out of memory"); +- return JIM_ERR; ++ return ERROR_FAIL; + } + INIT_LIST_HEAD(lh); + +- for (int i = 1; i < argc; i++) { +- struct target_list *new = create_target_list_node(argv[i]); ++ for (unsigned int i = 0; i < CMD_ARGC; i++) { ++ struct target_list *new = create_target_list_node(CMD_ARGV[i]); + if (new) + list_add_tail(&new->lh, lh); + } +@@ -6476,14 +6476,13 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) + smp_group++; + + struct target *rtos_target; +- int retval = get_target_with_common_rtos_type(lh, &rtos_target); +- if (retval == JIM_OK && rtos_target) ++ int retval = get_target_with_common_rtos_type(CMD, lh, &rtos_target); ++ if (retval == ERROR_OK && rtos_target) + retval = rtos_smp_init(rtos_target); + + return retval; + } + +- + static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) + { + struct jim_getopt_info goi; +@@ -6536,7 +6535,7 @@ static const struct command_registration target_subcommand_handlers[] = { + { + .name = "smp", + .mode = COMMAND_ANY, +- .jim_handler = jim_target_smp, ++ .handler = handle_target_smp, + .usage = "targetname1 targetname2 ...", + .help = "gather several target in a smp list" + }, diff --git a/meta-oe/recipes-devtools/openocd/openocd/0131-tcl-board-calao-usb-a9260-fix-and-refactor-broken-su.patch b/meta-oe/recipes-devtools/openocd/openocd/0131-tcl-board-calao-usb-a9260-fix-and-refactor-broken-su.patch new file mode 100644 index 000000000..805e2ee2f --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0131-tcl-board-calao-usb-a9260-fix-and-refactor-broken-su.patch @@ -0,0 +1,126 @@ +From f0e8f7b790f6d945c35b4bb868cafee5fcea3a22 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Fri, 3 Mar 2023 12:26:46 +0100 +Subject: [PATCH] tcl/board/calao-usb-a9260: fix and refactor broken support + +The old configuration files did not work because of a missing +'at91sam9260minimal.cfg' file. Also, the config files were placed +wrongly. Update them, put them to the proper location, merge the two +supported boards into one, remove now superfluous include, remove +defunct web page, etc.. Tested with a Calao USB-A9G20 and a hacked +'device_desc' to match. Native support for it will come next. + +Signed-off-by: Wolfram Sang +Change-Id: Iec578c8777c5a6134e132dbac17c2988c7634742 +Reviewed-on: https://review.openocd.org/c/openocd/+/7522 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + tcl/board/calao-usb-a9260.cfg | 14 +++++++++++++ + tcl/interface/calao-usb-a9260.cfg | 12 ----------- + tcl/interface/ftdi/calao-usb-a9260-c01.cfg | 24 ---------------------- + tcl/interface/ftdi/calao-usb-a9260-c02.cfg | 24 ---------------------- + 4 files changed, 14 insertions(+), 60 deletions(-) + create mode 100644 tcl/board/calao-usb-a9260.cfg + delete mode 100644 tcl/interface/calao-usb-a9260.cfg + delete mode 100644 tcl/interface/ftdi/calao-usb-a9260-c01.cfg + delete mode 100644 tcl/interface/ftdi/calao-usb-a9260-c02.cfg + +diff --git a/tcl/board/calao-usb-a9260.cfg b/tcl/board/calao-usb-a9260.cfg +new file mode 100644 +index 000000000..52fede0fa +--- /dev/null ++++ b/tcl/board/calao-usb-a9260.cfg +@@ -0,0 +1,14 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++# CALAO Systems USB-A9260 (C01 and C02) ++ ++adapter driver ftdi ++ftdi device_desc "USB-A9260" ++ftdi vid_pid 0x0403 0x6001 0x0403 0x6010 ++ftdi layout_init 0x0c08 0x0f1b ++ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 ++ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 ++ ++transport select jtag ++ ++source [find target/at91sam9260.cfg] +diff --git a/tcl/interface/calao-usb-a9260.cfg b/tcl/interface/calao-usb-a9260.cfg +deleted file mode 100644 +index ff652ef8f..000000000 +--- a/tcl/interface/calao-usb-a9260.cfg ++++ /dev/null +@@ -1,12 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-# +-# CALAO Systems USB-A9260 common -C01 -C02 setup +-# +-# http://www.calao-systems.com/ +-# +-# See calao-usb-a9260-c01.cfg and calao-usb-a9260-c02.cfg. +-# +- +-adapter srst delay 200 +-jtag_ntrst_delay 200 +diff --git a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg b/tcl/interface/ftdi/calao-usb-a9260-c01.cfg +deleted file mode 100644 +index c84e77874..000000000 +--- a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg ++++ /dev/null +@@ -1,24 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-# +-# CALAO Systems USB-A9260-C01 +-# +-# http://www.calao-systems.com/ +-# +- +-echo "WARNING!" +-echo "This file was not tested with real interface, but is assumed to work as this" +-echo "interface uses the same layout as configs that were verified. Please report your" +-echo "experience with this file to openocd-devel mailing list, so it could be marked" +-echo "as working or fixed." +- +-adapter driver ftdi +-ftdi device_desc "USB-A9260" +-ftdi vid_pid 0x0403 0x6010 +- +-ftdi layout_init 0x0c08 0x0f1b +-ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 +-ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 +- +-script interface/calao-usb-a9260.cfg +-script target/at91sam9260minimal.cfg +diff --git a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg b/tcl/interface/ftdi/calao-usb-a9260-c02.cfg +deleted file mode 100644 +index 9d79b2600..000000000 +--- a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg ++++ /dev/null +@@ -1,24 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-or-later +- +-# +-# CALAO Systems USB-A9260-C02 +-# +-# http://www.calao-systems.com/ +-# +- +-echo "WARNING!" +-echo "This file was not tested with real interface, but is assumed to work as this" +-echo "interface uses the same layout as configs that were verified. Please report your" +-echo "experience with this file to openocd-devel mailing list, so it could be marked" +-echo "as working or fixed." +- +-adapter driver ftdi +-ftdi device_desc "USB-A9260" +-ftdi vid_pid 0x0403 0x6001 +- +-ftdi layout_init 0x0c08 0x0f1b +-ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 +-ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 +- +-script interface/calao-usb-a9260.cfg +-script target/at91sam9260minimal.cfg diff --git a/meta-oe/recipes-devtools/openocd/openocd/0132-tcl-board-add-Calao-USB-A9G20.patch b/meta-oe/recipes-devtools/openocd/openocd/0132-tcl-board-add-Calao-USB-A9G20.patch new file mode 100644 index 000000000..c5a9202e2 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0132-tcl-board-add-Calao-USB-A9G20.patch @@ -0,0 +1,37 @@ +From b939224ab6e6e28e5211aac0303951ae4fabaf1f Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Sun, 5 Mar 2023 08:38:14 +0100 +Subject: [PATCH] tcl/board: add Calao USB-A9G20 + +Add a basic config. + +Signed-off-by: Wolfram Sang +Change-Id: Ie68e5fbb26b1c2f3028e561af0255fa71ec61828 +Reviewed-on: https://review.openocd.org/c/openocd/+/7524 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + tcl/board/calao-usb-a9g20-c01.cfg | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + create mode 100644 tcl/board/calao-usb-a9g20-c01.cfg + +diff --git a/tcl/board/calao-usb-a9g20-c01.cfg b/tcl/board/calao-usb-a9g20-c01.cfg +new file mode 100644 +index 000000000..6c4bd40fe +--- /dev/null ++++ b/tcl/board/calao-usb-a9g20-c01.cfg +@@ -0,0 +1,14 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++# CALAO Systems USB-A9G20-C01 ++ ++adapter driver ftdi ++ftdi device_desc "USB-A9G20" ++ftdi vid_pid 0x0403 0x6010 ++ftdi layout_init 0x0c08 0x0f1b ++ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 ++ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 ++ ++transport select jtag ++ ++source [find target/at91sam9g20.cfg] diff --git a/meta-oe/recipes-devtools/openocd/openocd/0133-flash-nor-missing-fileio_close.patch b/meta-oe/recipes-devtools/openocd/openocd/0133-flash-nor-missing-fileio_close.patch new file mode 100644 index 000000000..a2e26f843 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0133-flash-nor-missing-fileio_close.patch @@ -0,0 +1,28 @@ +From c1b14d678fd77095ef5c076c0e927aeed6a753c7 Mon Sep 17 00:00:00 2001 +From: panciyan +Date: Mon, 20 Mar 2023 02:26:58 +0000 +Subject: [PATCH] flash/nor: missing fileio_close. + +If the file read abnormally, need to close it which was opened before. + +Signed-off-by: panciyan +Change-Id: I6142f154741dcd38088b7add2793219ee4dd2ae9 +Reviewed-on: https://review.openocd.org/c/openocd/+/7546 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/flash/nor/tcl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c +index ecbcf00aa..22c1710ad 100644 +--- a/src/flash/nor/tcl.c ++++ b/src/flash/nor/tcl.c +@@ -814,6 +814,7 @@ COMMAND_HANDLER(handle_flash_write_bank_command) + if (buf_cnt != length) { + LOG_ERROR("Short read"); + free(buffer); ++ fileio_close(fileio); + return ERROR_FAIL; + } + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0134-github-workflow-increase-delete-tag-and-release-vers.patch b/meta-oe/recipes-devtools/openocd/openocd/0134-github-workflow-increase-delete-tag-and-release-vers.patch new file mode 100644 index 000000000..3c83dff10 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0134-github-workflow-increase-delete-tag-and-release-vers.patch @@ -0,0 +1,67 @@ +From 4b9b55a832e43815a1dd1b219107a01a1beadc1e Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Sat, 25 Mar 2023 02:56:19 +0300 +Subject: [PATCH] github/workflow: increase delete-tag-and-release version + +During setup job in the GH actions, GH tries to resolve +all actions before starting to run the scripts. +It can not find 0.2.0 version inside +'dev-drprasad/delete-tag-and-release 'repo and action fails. + +This patch fixes that error. +Also, switched to the latest ubuntu image +Hidapi version updated to 0.13.1 + +Signed-off-by: Erhan Kurubas +Change-Id: I02af41f6189d5a28f874c9b008073d74de46b4ca +Reviewed-on: https://review.openocd.org/c/openocd/+/7551 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + .github/workflows/snapshot.yml | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml +index e5997a055..b48388ef7 100644 +--- a/.github/workflows/snapshot.yml ++++ b/.github/workflows/snapshot.yml +@@ -8,7 +8,7 @@ name: OpenOCD Snapshot + + jobs: + package: +- runs-on: [ubuntu-18.04] ++ runs-on: [ubuntu-20.04] + env: + DL_DIR: ../downloads + BUILD_DIR: ../build +@@ -30,7 +30,7 @@ jobs: + echo "LIBUSB1_SRC=$PWD/libusb-${LIBUSB1_VER}" >> $GITHUB_ENV + - name: Prepare hidapi + env: +- HIDAPI_VER: 0.11.2 ++ HIDAPI_VER: 0.13.1 + run: | + mkdir -p $DL_DIR && cd $DL_DIR + wget "https://github.com/libusb/hidapi/archive/hidapi-${HIDAPI_VER}.tar.gz" +@@ -82,6 +82,7 @@ jobs: + # add missing dlls + cd $HOST-root/usr + cp `$HOST-gcc --print-file-name=libwinpthread-1.dll` ./bin/ ++ # required by libftdi1.dll. For the gcc-mingw-10.3.x or later "libgcc_s_dw2-1.dll" will need to be copied. + cp `$HOST-gcc --print-file-name=libgcc_s_sjlj-1.dll` ./bin/ + # prepare the artifact + ARTIFACT="openocd-${OPENOCD_TAG}-${HOST}.tar.gz" +@@ -90,11 +91,11 @@ jobs: + echo "IS_PRE_RELEASE=$IS_PRE_RELEASE" >> $GITHUB_ENV + echo "ARTIFACT_PATH=$PWD/$ARTIFACT" >> $GITHUB_ENV + - name: Publish OpenOCD packaged for windows +- uses: actions/upload-artifact@v2 ++ uses: actions/upload-artifact@v3 + with: + path: ${{ env.ARTIFACT_PATH }} + - name: Delete 'latest' Release +- uses: dev-drprasad/delete-tag-and-release@v0.2.0 ++ uses: dev-drprasad/delete-tag-and-release@v0.2.1 + with: + delete_release: true + tag_name: ${{ env.RELEASE_NAME }} diff --git a/meta-oe/recipes-devtools/openocd/openocd/0135-github-workflow-build-libjaylink-from-source.patch b/meta-oe/recipes-devtools/openocd/openocd/0135-github-workflow-build-libjaylink-from-source.patch new file mode 100644 index 000000000..e708be032 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0135-github-workflow-build-libjaylink-from-source.patch @@ -0,0 +1,96 @@ +From 99ec5760961d264599a9c9fb1a4d5d6042bc3ba8 Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Sat, 25 Mar 2023 03:00:51 +0300 +Subject: [PATCH] github/workflow: build libjaylink from source + +Libjaylink submodule disabled by default at +https://review.openocd.org/c/openocd/+/7129 + +--enable-internal-libjaylink config option will be deprecated soon. + +So, building the source is a permanent solution. + +Signed-off-by: Erhan Kurubas +Change-Id: Id06654d806a3a49f35e3ba41e9e4cc58c1a0d388 +Reviewed-on: https://review.openocd.org/c/openocd/+/7552 +Tested-by: jenkins +Reviewed-by: zapb +Reviewed-by: Antonio Borneo +--- + .github/workflows/snapshot.yml | 11 +++++++++++ + contrib/cross-build.sh | 13 +++++++++++++ + 2 files changed, 24 insertions(+) + +diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml +index b48388ef7..f5cf56459 100644 +--- a/.github/workflows/snapshot.yml ++++ b/.github/workflows/snapshot.yml +@@ -56,6 +56,16 @@ jobs: + wget "https://github.com/aquynh/capstone/archive/${CAPSTONE_VER}.tar.gz" + tar -xzf ${CAPSTONE_VER}.tar.gz + echo "CAPSTONE_SRC=$PWD/capstone-${CAPSTONE_VER}" >> $GITHUB_ENV ++ - name: Prepare libjaylink ++ env: ++ LIBJAYLINK_VER: 0.3.1 ++ run: | ++ mkdir -p $DL_DIR && cd $DL_DIR ++ wget https://gitlab.zapb.de/libjaylink/libjaylink/-/archive/${LIBJAYLINK_VER}/libjaylink-${LIBJAYLINK_VER}.tar.gz ++ tar -xzf libjaylink-${LIBJAYLINK_VER}.tar.gz ++ cd libjaylink-${LIBJAYLINK_VER} ++ ./autogen.sh ++ echo "LIBJAYLINK_SRC=$PWD" >> $GITHUB_ENV + - name: Package OpenOCD for windows + env: + MAKE_JOBS: 2 +@@ -64,6 +74,7 @@ jobs: + HIDAPI_CONFIG: --enable-shared --disable-static --disable-testgui + LIBFTDI_CONFIG: -DSTATICLIBS=OFF -DEXAMPLES=OFF -DFTDI_EEPROM=OFF + CAPSTONE_CONFIG: "CAPSTONE_BUILD_CORE_ONLY=yes CAPSTONE_STATIC=yes CAPSTONE_SHARED=no" ++ LIBJAYLINK_CONFIG: --enable-shared --disable-static + run: | + # check if there is tag pointing at HEAD, otherwise take the HEAD SHA-1 as OPENOCD_TAG + OPENOCD_TAG="`git tag --points-at HEAD`" +diff --git a/contrib/cross-build.sh b/contrib/cross-build.sh +index b199bf715..bb8c8c47d 100755 +--- a/contrib/cross-build.sh ++++ b/contrib/cross-build.sh +@@ -41,12 +41,14 @@ WORK_DIR=$PWD + : ${HIDAPI_SRC:=/path/to/hidapi} + : ${LIBFTDI_SRC:=/path/to/libftdi} + : ${CAPSTONE_SRC:=/path/to/capstone} ++: ${LIBJAYLINK_SRC:=/path/to/libjaylink} + + OPENOCD_SRC=`readlink -m $OPENOCD_SRC` + LIBUSB1_SRC=`readlink -m $LIBUSB1_SRC` + HIDAPI_SRC=`readlink -m $HIDAPI_SRC` + LIBFTDI_SRC=`readlink -m $LIBFTDI_SRC` + CAPSTONE_SRC=`readlink -m $CAPSTONE_SRC` ++LIBJAYLINK_SRC=`readlink -m $LIBJAYLINK_SRC` + + HOST_TRIPLET=$1 + BUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build +@@ -54,6 +56,7 @@ LIBUSB1_BUILD_DIR=$BUILD_DIR/libusb1 + HIDAPI_BUILD_DIR=$BUILD_DIR/hidapi + LIBFTDI_BUILD_DIR=$BUILD_DIR/libftdi + CAPSTONE_BUILD_DIR=$BUILD_DIR/capstone ++LIBJAYLINK_BUILD_DIR=$BUILD_DIR/libjaylink + OPENOCD_BUILD_DIR=$BUILD_DIR/openocd + + ## Root of host file tree +@@ -158,6 +161,16 @@ libdir=${exec_prefix}/lib \ + includedir=${prefix}/include/capstone\n\n;' $CAPSTONE_PC_FILE + fi + ++# libjaylink build & install into sysroot ++if [ -d $LIBJAYLINK_SRC ] ; then ++ mkdir -p $LIBJAYLINK_BUILD_DIR ++ cd $LIBJAYLINK_BUILD_DIR ++ $LIBJAYLINK_SRC/configure --build=`$LIBJAYLINK_SRC/config.guess` --host=$HOST_TRIPLET \ ++ --with-sysroot=$SYSROOT --prefix=$PREFIX \ ++ $LIBJAYLINK_CONFIG ++ make -j $MAKE_JOBS ++ make install DESTDIR=$SYSROOT ++fi + + # OpenOCD build & install into sysroot + mkdir -p $OPENOCD_BUILD_DIR diff --git a/meta-oe/recipes-devtools/openocd/openocd/0136-rtos-FreeRTOS-some-optimization-of-freertos_update_t.patch b/meta-oe/recipes-devtools/openocd/openocd/0136-rtos-FreeRTOS-some-optimization-of-freertos_update_t.patch new file mode 100644 index 000000000..db4c64b91 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0136-rtos-FreeRTOS-some-optimization-of-freertos_update_t.patch @@ -0,0 +1,51 @@ +From 41037eb26585114209c3c8f1d63f7788a421df07 Mon Sep 17 00:00:00 2001 +From: Chao Du +Date: Wed, 22 Mar 2023 06:51:51 +0000 +Subject: [PATCH] rtos/FreeRTOS: some optimization of freertos_update_threads() + +1. +update the rtos->thread_count in time, to make sure the allocated +thread_name_str and extra_info_str could be freed by +rtos_free_threadlist(). Otherwise the abnormal return may cause a +memory leak. +2. +remove a redundant assignment to threadid. + +Signed-off-by: Chao Du +Change-Id: Ifabc59d501c925b3d6aec8b04b2856d2c31cc4e2 +Reviewed-on: https://review.openocd.org/c/openocd/+/7549 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +Reviewed-by: Antonio Borneo +--- + src/rtos/FreeRTOS.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c +index 070275f2c..e8df030aa 100644 +--- a/src/rtos/FreeRTOS.c ++++ b/src/rtos/FreeRTOS.c +@@ -312,7 +312,6 @@ static int freertos_update_threads(struct rtos *rtos) + (list_elem_ptr != prev_list_elem_ptr) && + (tasks_found < thread_list_size)) { + /* Get the location of the thread structure. */ +- rtos->thread_details[tasks_found].threadid = 0; + retval = target_read_u32(rtos->target, + list_elem_ptr + param->list_elem_content_offset, + &pointer_casts_are_bad); +@@ -365,6 +364,7 @@ static int freertos_update_threads(struct rtos *rtos) + + tasks_found++; + list_thread_count--; ++ rtos->thread_count = tasks_found; + + prev_list_elem_ptr = list_elem_ptr; + list_elem_ptr = 0; +@@ -383,7 +383,6 @@ static int freertos_update_threads(struct rtos *rtos) + } + + free(list_of_lists); +- rtos->thread_count = tasks_found; + return 0; + } + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0137-src-target-mips_m4k-fix-condition-on-overlapping-wor.patch b/meta-oe/recipes-devtools/openocd/openocd/0137-src-target-mips_m4k-fix-condition-on-overlapping-wor.patch new file mode 100644 index 000000000..b0626e47a --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0137-src-target-mips_m4k-fix-condition-on-overlapping-wor.patch @@ -0,0 +1,38 @@ +From 18aacc8bf3ff7c7481673cbbfe82f0104e4dccf9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fran=C3=A7ois=20LEGAL?= +Date: Wed, 29 Mar 2023 14:19:48 +0200 +Subject: [PATCH] src/target/mips_m4k : fix condition on overlapping workspace + data area +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The condition to check if the workspace area (used by actual MIPS code +executed on target) and data area (sandbox to put data to be read/written +to/from flash) is wrong, thus preventing the use of FAST_* commands to +program/verify FLASH. + +Signed-off-by: François LEGAL +Change-Id: Ic68424b7f42d44e550433a120093db5e7980fd56 +Reviewed-on: https://review.openocd.org/c/openocd/+/7563 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/target/mips_m4k.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c +index 491b247b1..d3b07585d 100644 +--- a/src/target/mips_m4k.c ++++ b/src/target/mips_m4k.c +@@ -1218,8 +1218,8 @@ static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t addre + + fast_data_area = mips32->fast_data_area; + +- if (address <= fast_data_area->address + fast_data_area->size && +- fast_data_area->address <= address + count) { ++ if (address < (fast_data_area->address + fast_data_area->size) && ++ fast_data_area->address < (address + count)) { + LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area " + "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").", + fast_data_area->address, address, address + count); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0138-src-target-mips_m4k-add-fast-read-method.patch b/meta-oe/recipes-devtools/openocd/openocd/0138-src-target-mips_m4k-add-fast-read-method.patch new file mode 100644 index 000000000..5f6ddaf59 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0138-src-target-mips_m4k-add-fast-read-method.patch @@ -0,0 +1,119 @@ +From 55e04e3157cd4d817cfd39c6f1384f96d61a0951 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fran=C3=A7ois=20LEGAL?= +Date: Wed, 29 Mar 2023 17:46:38 +0200 +Subject: [PATCH] src/target/mips_m4k : add fast read method +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add the fast read method to speed up flash verification +after programming. Works the same as fast write already +implemented. + +Signed-off-by: François LEGAL +Change-Id: I74611a3542a88212f0483ec8ee368aba3d1f03c7 +Reviewed-on: https://review.openocd.org/c/openocd/+/7564 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/target/mips_m4k.c | 73 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c +index d3b07585d..14e3f3b27 100644 +--- a/src/target/mips_m4k.c ++++ b/src/target/mips_m4k.c +@@ -36,6 +36,8 @@ static int mips_m4k_internal_restore(struct target *target, int current, + static int mips_m4k_halt(struct target *target); + static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address, + uint32_t count, const uint8_t *buffer); ++static int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address, ++ uint32_t count, uint8_t *buffer); + + static int mips_m4k_examine_debug_reason(struct target *target) + { +@@ -1021,6 +1023,12 @@ static int mips_m4k_read_memory(struct target *target, target_addr_t address, + if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) + return ERROR_TARGET_UNALIGNED_ACCESS; + ++ if (size == 4 && count > 32) { ++ int retval = mips_m4k_bulk_read_memory(target, address, count, buffer); ++ if (retval == ERROR_OK) ++ return ERROR_OK; ++ LOG_WARNING("Falling back to non-bulk read"); ++ } + /* since we don't know if buffer is aligned, we allocate new mem that is always aligned */ + void *t = NULL; + +@@ -1249,6 +1257,71 @@ static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t addre + return retval; + } + ++static int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address, ++ uint32_t count, uint8_t *buffer) ++{ ++ struct mips32_common *mips32 = target_to_mips32(target); ++ struct mips_ejtag *ejtag_info = &mips32->ejtag_info; ++ struct working_area *fast_data_area; ++ int retval; ++ int write_t = 0; ++ ++ LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "", ++ address, count); ++ ++ /* check alignment */ ++ if (address & 0x3u) ++ return ERROR_TARGET_UNALIGNED_ACCESS; ++ ++ if (!mips32->fast_data_area) { ++ /* Get memory for block read handler ++ * we preserve this area between calls and gain a speed increase ++ * of about 3kb/sec when reading flash ++ * this will be released/nulled by the system when the target is resumed or reset */ ++ retval = target_alloc_working_area(target, ++ MIPS32_FASTDATA_HANDLER_SIZE, ++ &mips32->fast_data_area); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("No working area available"); ++ return retval; ++ } ++ ++ /* reset fastadata state so the algo get reloaded */ ++ ejtag_info->fast_access_save = -1; ++ } ++ ++ fast_data_area = mips32->fast_data_area; ++ ++ if (address < (fast_data_area->address + fast_data_area->size) && ++ fast_data_area->address < (address + count)) { ++ LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within read area " ++ "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").", ++ fast_data_area->address, address, address + count); ++ LOG_ERROR("Change work-area-phys or load_image address!"); ++ return ERROR_FAIL; ++ } ++ ++ /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */ ++ /* but byte array represents target endianness */ ++ uint32_t *t = malloc(count * sizeof(uint32_t)); ++ if (!t) { ++ LOG_ERROR("Out of memory"); ++ return ERROR_FAIL; ++ } ++ ++ retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address, ++ count, t); ++ ++ target_buffer_set_u32_array(target, buffer, count, t); ++ ++ free(t); ++ ++ if (retval != ERROR_OK) ++ LOG_ERROR("Fastdata access Failed"); ++ ++ return retval; ++} ++ + static int mips_m4k_verify_pointer(struct command_invocation *cmd, + struct mips_m4k_common *mips_m4k) + { diff --git a/meta-oe/recipes-devtools/openocd/openocd/0139-helper-list-remove-unused-hlist_.patch b/meta-oe/recipes-devtools/openocd/openocd/0139-helper-list-remove-unused-hlist_.patch new file mode 100644 index 000000000..cae7e0de6 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0139-helper-list-remove-unused-hlist_.patch @@ -0,0 +1,285 @@ +From 90ce9da644d751466d8dc451d7d2a043cdbf7d72 Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Tue, 14 Mar 2023 15:01:18 +0100 +Subject: [PATCH] helper/list: remove unused hlist_* + +The file list.h is taken from Linux and includes two similar +implementation of double linked lists: +- with single linked list's head (hlist_*), and +- with double linked list's head (list_*). +While the former offers a minor memory footprint improvement, +keeping two implementations makes harder for newbie developers +to approach them. + +So far only the latter implementation has been used and no new +patches in gerrit is going to change that. + +Drop the support for lists with single linked head. +It can be easily taken back from git history, if needed. + +Change-Id: I420e5de38ab755fdfbeb2115538c61818308ec2b +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7567 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/helper/list.h | 239 +--------------------------------------------- + 1 file changed, 1 insertion(+), 238 deletions(-) + +diff --git a/src/helper/list.h b/src/helper/list.h +index 552a3202a..396ff06c9 100644 +--- a/src/helper/list.h ++++ b/src/helper/list.h +@@ -27,13 +27,6 @@ struct list_head { + struct list_head *next, *prev; + }; + +-struct hlist_head { +- struct hlist_node *first; +-}; +- +-struct hlist_node { +- struct hlist_node *next, **pprev; +-}; + /* end local changes */ + + /* +@@ -811,237 +804,7 @@ static inline void list_splice_tail_init(struct list_head *list, + + /* + * Double linked lists with a single pointer list head. +- * Mostly useful for hash tables where the two pointer list head is +- * too wasteful. +- * You lose the ability to access the tail in O(1). +- */ +- +-#define HLIST_HEAD_INIT { .first = NULL } +-#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } +-#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +-static inline void INIT_HLIST_NODE(struct hlist_node *h) +-{ +- h->next = NULL; +- h->pprev = NULL; +-} +- +-/** +- * hlist_unhashed - Has node been removed from list and reinitialized? +- * @param h Node to be checked +- * +- * Not that not all removal functions will leave a node in unhashed +- * state. For example, hlist_nulls_del_init_rcu() does leave the +- * node in unhashed state, but hlist_nulls_del() does not. +- */ +-static inline int hlist_unhashed(const struct hlist_node *h) +-{ +- return !h->pprev; +-} +- +-/* Ignore kernel hlist_unhashed_lockless() */ +- +-/** +- * hlist_empty - Is the specified hlist_head structure an empty hlist? +- * @param h Structure to check. +- */ +-static inline int hlist_empty(const struct hlist_head *h) +-{ +- return !h->first; +-} +- +-static inline void __hlist_del(struct hlist_node *n) +-{ +- struct hlist_node *next = n->next; +- struct hlist_node **pprev = n->pprev; +- +- *pprev = next; +- if (next) +- next->pprev = pprev; +-} +- +-/** +- * hlist_del - Delete the specified hlist_node from its list +- * @param n Node to delete. +- * +- * Note that this function leaves the node in hashed state. Use +- * hlist_del_init() or similar instead to unhash @a n. +- */ +-static inline void hlist_del(struct hlist_node *n) +-{ +- __hlist_del(n); +- n->next = LIST_POISON1; +- n->pprev = LIST_POISON2; +-} +- +-/** +- * hlist_del_init - Delete the specified hlist_node from its list and initialize +- * @param n Node to delete. +- * +- * Note that this function leaves the node in unhashed state. +- */ +-static inline void hlist_del_init(struct hlist_node *n) +-{ +- if (!hlist_unhashed(n)) { +- __hlist_del(n); +- INIT_HLIST_NODE(n); +- } +-} +- +-/** +- * hlist_add_head - add a new entry at the beginning of the hlist +- * @param n new entry to be added +- * @param h hlist head to add it after +- * +- * Insert a new entry after the specified head. +- * This is good for implementing stacks. +- */ +-static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +-{ +- struct hlist_node *first = h->first; +- n->next = first; +- if (first) +- first->pprev = &n->next; +- h->first = n; +- n->pprev = &h->first; +-} +- +-/** +- * hlist_add_before - add a new entry before the one specified +- * @param n new entry to be added +- * @param next hlist node to add it before, which must be non-NULL +- */ +-static inline void hlist_add_before(struct hlist_node *n, +- struct hlist_node *next) +-{ +- n->pprev = next->pprev; +- n->next = next; +- next->pprev = &n->next; +- *(n->pprev) = n; +-} +- +-/** +- * hlist_add_behind - add a new entry after the one specified +- * @param n new entry to be added +- * @param prev hlist node to add it after, which must be non-NULL +- */ +-static inline void hlist_add_behind(struct hlist_node *n, +- struct hlist_node *prev) +-{ +- n->next = prev->next; +- prev->next = n; +- n->pprev = &prev->next; +- +- if (n->next) +- n->next->pprev = &n->next; +-} +- +-/** +- * hlist_add_fake - create a fake hlist consisting of a single headless node +- * @param n Node to make a fake list out of +- * +- * This makes @a n appear to be its own predecessor on a headless hlist. +- * The point of this is to allow things like hlist_del() to work correctly +- * in cases where there is no list. +- */ +-static inline void hlist_add_fake(struct hlist_node *n) +-{ +- n->pprev = &n->next; +-} +- +-/** +- * hlist_fake: Is this node a fake hlist? +- * @param h Node to check for being a self-referential fake hlist. +- */ +-static inline bool hlist_fake(struct hlist_node *h) +-{ +- return h->pprev == &h->next; +-} +- +-/** +- * hlist_is_singular_node - is node the only element of the specified hlist? +- * @param n Node to check for singularity. +- * @param h Header for potentially singular list. +- * +- * Check whether the node is the only node of the head without +- * accessing head, thus avoiding unnecessary cache misses. +- */ +-static inline bool +-hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) +-{ +- return !n->next && n->pprev == &h->first; +-} +- +-/** +- * hlist_move_list - Move an hlist +- * @param old hlist_head for old list. +- * @param new hlist_head for new list. +- * +- * Move a list from one list head to another. Fixup the pprev +- * reference of the first entry if it exists. +- */ +-static inline void hlist_move_list(struct hlist_head *old, +- struct hlist_head *new) +-{ +- new->first = old->first; +- if (new->first) +- new->first->pprev = &new->first; +- old->first = NULL; +-} +- +-#define hlist_entry(ptr, type, member) container_of(ptr, type, member) +- +-#define hlist_for_each(pos, head) \ +- for (pos = (head)->first; pos ; pos = pos->next) +- +-#define hlist_for_each_safe(pos, n, head) \ +- for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ +- pos = n) +- +-#define hlist_entry_safe(ptr, type, member) \ +- ({ typeof(ptr) ____ptr = (ptr); \ +- ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ +- }) +- +-/** +- * hlist_for_each_entry - iterate over list of given type +- * @param pos the type * to use as a loop cursor. +- * @param head the head for your list. +- * @param member the name of the hlist_node within the struct. +- */ +-#define hlist_for_each_entry(pos, head, member) \ +- for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ +- pos; \ +- pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) +- +-/** +- * hlist_for_each_entry_continue - iterate over a hlist continuing after current point +- * @param pos the type * to use as a loop cursor. +- * @param member the name of the hlist_node within the struct. +- */ +-#define hlist_for_each_entry_continue(pos, member) \ +- for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ +- pos; \ +- pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) +- +-/** +- * hlist_for_each_entry_from - iterate over a hlist continuing from current point +- * @param pos the type * to use as a loop cursor. +- * @param member the name of the hlist_node within the struct. +- */ +-#define hlist_for_each_entry_from(pos, member) \ +- for (; pos; \ +- pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) +- +-/** +- * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry +- * @param pos the type * to use as a loop cursor. +- * @param n a &struct hlist_node to use as temporary storage +- * @param head the head for your list. +- * @param member the name of the hlist_node within the struct. ++ * IGNORED + */ +-#define hlist_for_each_entry_safe(pos, n, head, member) \ +- for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ +- pos && ({ n = pos->member.next; 1; }); \ +- pos = hlist_entry_safe(n, typeof(*pos), member)) + + #endif /* OPENOCD_HELPER_LIST_H */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0140-helper-list-re-align-with-Linux-kernel-6.3-rc1.patch b/meta-oe/recipes-devtools/openocd/openocd/0140-helper-list-re-align-with-Linux-kernel-6.3-rc1.patch new file mode 100644 index 000000000..b3cb8cf66 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0140-helper-list-re-align-with-Linux-kernel-6.3-rc1.patch @@ -0,0 +1,145 @@ +From c8de1b82ec7f74c0717bfa0094f5fb6b79fbbfaf Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Tue, 14 Mar 2023 15:20:14 +0100 +Subject: [PATCH] helper/list: re-align with Linux kernel 6.3-rc1 + +Minor changes due to kernel switch to 100 char/line. +Added four new functions. + +Silent checkpatch; we don't want to diverge from Linux reference +code. +Checkpatch-ignore: MACRO_ARG_REUSE, UNNECESSARY_PARENTHESES +Checkpatch-ignore: MACRO_ARG_PRECEDENCE + +Change-Id: I1d2ff25bf3bab8cd0f5c9be55c7501795490ea75 +Signed-off-by: Antonio Borneo +Reviewed-on: https://review.openocd.org/c/openocd/+/7568 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + src/helper/list.h | 66 +++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 58 insertions(+), 8 deletions(-) + +diff --git a/src/helper/list.h b/src/helper/list.h +index 396ff06c9..c9de0569b 100644 +--- a/src/helper/list.h ++++ b/src/helper/list.h +@@ -265,8 +265,7 @@ static inline void list_bulk_move_tail(struct list_head *head, + * @param list the entry to test + * @param head the head of the list + */ +-static inline int list_is_first(const struct list_head *list, +- const struct list_head *head) ++static inline int list_is_first(const struct list_head *list, const struct list_head *head) + { + return list->prev == head; + } +@@ -276,12 +275,21 @@ static inline int list_is_first(const struct list_head *list, + * @param list the entry to test + * @param head the head of the list + */ +-static inline int list_is_last(const struct list_head *list, +- const struct list_head *head) ++static inline int list_is_last(const struct list_head *list, const struct list_head *head) + { + return list->next == head; + } + ++/** ++ * list_is_head - tests whether @a list is the list @a head ++ * @param list the entry to test ++ * @param head the head of the list ++ */ ++static inline int list_is_head(const struct list_head *list, const struct list_head *head) ++{ ++ return list == head; ++} ++ + /** + * list_empty - tests whether a list is empty + * @param head the list to test. +@@ -400,10 +408,9 @@ static inline void list_cut_position(struct list_head *list, + { + if (list_empty(head)) + return; +- if (list_is_singular(head) && +- (head->next != entry && head != entry)) ++ if (list_is_singular(head) && !list_is_head(entry, head) && (entry != head->next)) + return; +- if (entry == head) ++ if (list_is_head(entry, head)) + INIT_LIST_HEAD(list); + else + __list_cut_position(list, head, entry); +@@ -563,6 +570,19 @@ static inline void list_splice_tail_init(struct list_head *list, + #define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) + ++/** ++ * list_next_entry_circular - get the next element in list ++ * @param pos the type * to cursor. ++ * @param head the list head to take the element from. ++ * @param member the name of the list_head within the struct. ++ * ++ * Wraparound if pos is the last element (return the first element). ++ * Note, that list is expected to be not empty. ++ */ ++#define list_next_entry_circular(pos, head, member) \ ++ (list_is_last(&(pos)->member, head) ? \ ++ list_first_entry(head, typeof(*(pos)), member) : list_next_entry(pos, member)) ++ + /** + * list_prev_entry - get the prev element in list + * @param pos the type * to cursor +@@ -571,13 +591,28 @@ static inline void list_splice_tail_init(struct list_head *list, + #define list_prev_entry(pos, member) \ + list_entry((pos)->member.prev, typeof(*(pos)), member) + ++/** ++ * list_prev_entry_circular - get the prev element in list ++ * @param pos the type * to cursor. ++ * @param head the list head to take the element from. ++ * @param member the name of the list_head within the struct. ++ * ++ * Wraparound if pos is the first element (return the last element). ++ * Note, that list is expected to be not empty. ++ */ ++#define list_prev_entry_circular(pos, head, member) \ ++ (list_is_first(&(pos)->member, head) ? \ ++ list_last_entry(head, typeof(*(pos)), member) : list_prev_entry(pos, member)) ++ + /** + * list_for_each - iterate over a list + * @param pos the &struct list_head to use as a loop cursor. + * @param head the head for your list. + */ + #define list_for_each(pos, head) \ +- for (pos = (head)->next; pos != (head); pos = pos->next) ++ for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) ++ ++/* Ignore kernel list_for_each_rcu() */ + + /** + * list_for_each_continue - continue iteration over a list +@@ -618,6 +653,21 @@ static inline void list_splice_tail_init(struct list_head *list, + pos != (head); \ + pos = n, n = pos->prev) + ++/** ++ * list_count_nodes - count nodes in the list ++ * @param head the head for your list. ++ */ ++static inline size_t list_count_nodes(struct list_head *head) ++{ ++ struct list_head *pos; ++ size_t count = 0; ++ ++ list_for_each(pos, head) ++ count++; ++ ++ return count; ++} ++ + /** + * list_entry_is_head - test if the entry points to the head of the list + * @param pos the type * to cursor diff --git a/meta-oe/recipes-devtools/openocd/openocd/0141-ipdbg-whitespaces.patch b/meta-oe/recipes-devtools/openocd/openocd/0141-ipdbg-whitespaces.patch new file mode 100644 index 000000000..35c82ba6f --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0141-ipdbg-whitespaces.patch @@ -0,0 +1,100 @@ +From 7e0797d19ac1837e3001df9d45030b5eb97ca36d Mon Sep 17 00:00:00 2001 +From: Daniel Anselmi +Date: Wed, 14 Dec 2022 12:51:48 +0100 +Subject: [PATCH] ipdbg: whitespaces + +Change-Id: I9294c551cf2e795ad5e3e92dc3926c564424e067 +Signed-off-by: Daniel Anselmi +Reviewed-on: https://review.openocd.org/c/openocd/+/7399 +Tested-by: jenkins +Reviewed-by: Jonathan McDowell +Reviewed-by: Antonio Borneo +--- + src/server/ipdbg.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c +index f4a6f6cdc..755d0510e 100644 +--- a/src/server/ipdbg.c ++++ b/src/server/ipdbg.c +@@ -90,7 +90,7 @@ static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo) + return; + + size_t ri = fifo->rd_idx; +- for (size_t idx = 0 ; idx < fifo->count ; ++idx) ++ for (size_t idx = 0; idx < fifo->count; ++idx) + fifo->buffer[idx] = fifo->buffer[ri++]; + fifo->rd_idx = 0; + } +@@ -149,7 +149,7 @@ static int ipdbg_max_tools_from_data_register_length(uint8_t data_register_lengt + static struct ipdbg_service *ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool) + { + struct ipdbg_service *service; +- for (service = ipdbg_first_service ; service ; service = service->next) { ++ for (service = ipdbg_first_service; service; service = service->next) { + if (service->hub == hub && service->tool == tool) + break; + } +@@ -160,7 +160,7 @@ static void ipdbg_add_service(struct ipdbg_service *service) + { + struct ipdbg_service *iservice; + if (ipdbg_first_service) { +- for (iservice = ipdbg_first_service ; iservice->next; iservice = iservice->next) ++ for (iservice = ipdbg_first_service; iservice->next; iservice = iservice->next) + ; + iservice->next = service; + } else +@@ -192,7 +192,7 @@ static int ipdbg_remove_service(struct ipdbg_service *service) + return ERROR_OK; + } + +- for (struct ipdbg_service *iservice = ipdbg_first_service ; iservice->next ; iservice = iservice->next) { ++ for (struct ipdbg_service *iservice = ipdbg_first_service; iservice->next; iservice = iservice->next) { + if (service == iservice->next) { + iservice->next = service->next; + return ERROR_OK; +@@ -205,7 +205,7 @@ static struct ipdbg_hub *ipdbg_find_hub(struct jtag_tap *tap, + uint32_t user_instruction, struct ipdbg_virtual_ir_info *virtual_ir) + { + struct ipdbg_hub *hub = NULL; +- for (hub = ipdbg_first_hub ; hub ; hub = hub->next) { ++ for (hub = ipdbg_first_hub; hub; hub = hub->next) { + if (hub->tap == tap && hub->user_instruction == user_instruction) { + if ((!virtual_ir && !hub->virtual_ir) || + (virtual_ir && hub->virtual_ir && +@@ -223,7 +223,7 @@ static void ipdbg_add_hub(struct ipdbg_hub *hub) + { + struct ipdbg_hub *ihub; + if (ipdbg_first_hub) { +- for (ihub = ipdbg_first_hub ; ihub->next; ihub = ihub->next) ++ for (ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next) + ; + ihub->next = hub; + } else +@@ -281,7 +281,7 @@ static int ipdbg_remove_hub(struct ipdbg_hub *hub) + return ERROR_OK; + } + +- for (struct ipdbg_hub *ihub = ipdbg_first_hub ; ihub->next ; ihub = ihub->next) { ++ for (struct ipdbg_hub *ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next) { + if (hub == ihub->next) { + ihub->next = hub->next; + return ERROR_OK; +@@ -447,7 +447,7 @@ static int ipdbg_polling_callback(void *priv) + + /* transfer dn buffers to jtag-hub */ + unsigned int num_transfers = 0; +- for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) { ++ for (size_t tool = 0; tool < hub->max_tools; ++tool) { + struct connection *conn = hub->connections[tool]; + if (conn && conn->priv) { + struct ipdbg_connection *connection = conn->priv; +@@ -475,7 +475,7 @@ static int ipdbg_polling_callback(void *priv) + } + + /* write from up fifos to sockets */ +- for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) { ++ for (size_t tool = 0; tool < hub->max_tools; ++tool) { + struct connection *conn = hub->connections[tool]; + if (conn && conn->priv) { + struct ipdbg_connection *connection = conn->priv; diff --git a/meta-oe/recipes-devtools/openocd/openocd/0142-helper-compiler-fix-build-with-gcc-on-MacOS.patch b/meta-oe/recipes-devtools/openocd/openocd/0142-helper-compiler-fix-build-with-gcc-on-MacOS.patch new file mode 100644 index 000000000..8005111b6 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0142-helper-compiler-fix-build-with-gcc-on-MacOS.patch @@ -0,0 +1,40 @@ +From 561f27fde9dc51f014b672c227dc7c8ca2530fcf Mon Sep 17 00:00:00 2001 +From: Antonio Borneo +Date: Sun, 2 Apr 2023 14:24:23 +0200 +Subject: [PATCH] helper/compiler fix build with gcc on MacOS + +On MacOS libc includes files from MacOSX.sdk that define the macro + #define __nonnull +without arguments, causing compile error. + +Extend the existing check for clang on MacOS and undefine the +macro for gcc too. + +Change-Id: Ic99de78348c6aa86561212a3aded9342e5d32e02 +Signed-off-by: Antonio Borneo +Reported-by: Erhan Kurubas +Reviewed-on: https://review.openocd.org/c/openocd/+/7571 +Reviewed-by: Erhan Kurubas +Tested-by: jenkins +--- + src/helper/compiler.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/helper/compiler.h b/src/helper/compiler.h +index 33a075d64..312d261fc 100644 +--- a/src/helper/compiler.h ++++ b/src/helper/compiler.h +@@ -36,9 +36,11 @@ + * clang for Apple defines + * #define __nonnull _Nonnull + * that is a per argument attribute, incompatible with the gcc per function attribute __nonnull__. +- * Undefine it to keep compatibility among compilers. ++ * gcc for Apple includes sys/cdefs.h from MacOSX.sdk that defines ++ * #define __nonnull ++ * In both cases, undefine __nonnull to keep compatibility among compilers and platforms. + */ +-#if defined(__clang__) && defined(__APPLE__) ++#if defined(__APPLE__) + # undef __nonnull + #endif + #ifndef __nonnull diff --git a/meta-oe/recipes-devtools/openocd/openocd/0143-tcl-zynq_7000-add-missing-id-codes.patch b/meta-oe/recipes-devtools/openocd/openocd/0143-tcl-zynq_7000-add-missing-id-codes.patch new file mode 100644 index 000000000..39249f4cc --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0143-tcl-zynq_7000-add-missing-id-codes.patch @@ -0,0 +1,59 @@ +From e87fa5e3ab424d3ccd66eeddccfbe1e0181e20d0 Mon Sep 17 00:00:00 2001 +From: Daniel Anselmi +Date: Wed, 30 Nov 2022 03:42:18 +0100 +Subject: [PATCH] tcl: zynq_7000: add missing id codes + +Add missing ID codes and ignore the version in the ID. + +Change-Id: Idd2d3a5eddb6995f3af1c45afd2adf76ce3442bf +Signed-off-by: Daniel Anselmi +Reviewed-on: https://review.openocd.org/c/openocd/+/7386 +Tested-by: jenkins +Reviewed-by: Tomas Vanek +--- + tcl/target/zynq_7000.cfg | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/tcl/target/zynq_7000.cfg b/tcl/target/zynq_7000.cfg +index 0272587c1..a6f899541 100644 +--- a/tcl/target/zynq_7000.cfg ++++ b/tcl/target/zynq_7000.cfg +@@ -1,18 +1,34 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + +-# + # Xilinx Zynq-7000 All Programmable SoC + # + # http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm ++# https://www.xilinx.com/member/forms/download/sim-model-eval-license-xef.html?filename=bsdl_zynq_2.zip + # ++# 0x03736093 XQ7Z100 XC7Z100I XC7Z100 ++# 0x03731093 XQ7Z045 XC7Z045I XC7Z045 ++# 0x0372c093 XQ7Z030 XC7Z030I XC7Z030 XA7Z030 ++# 0x03727093 XQ7Z020 XC7Z020I XC7Z020 XA7Z020 ++# 0x03732093 XC7Z035I XC7Z035 ++# 0x0373b093 XC7Z015I XC7Z015 ++# 0x03728093 XC7Z014S ++# 0x0373c093 XC7Z012S ++# 0x03722093 XC7Z010I XC7Z010 XA7Z010 ++# 0x03723093 XC7Z007S + + set _CHIPNAME zynq + set _TARGETNAME $_CHIPNAME.cpu + +-jtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \ +- -expected-id 0x23727093 \ +- -expected-id 0x13722093 \ ++jtag newtap zynq_pl bs -irlen 6 -ignore-version -ircapture 0x1 -irmask 0x03 \ ++ -expected-id 0x03723093 \ ++ -expected-id 0x03722093 \ ++ -expected-id 0x0373c093 \ ++ -expected-id 0x03728093 \ ++ -expected-id 0x0373B093 \ ++ -expected-id 0x03732093 \ + -expected-id 0x03727093 \ ++ -expected-id 0x0372C093 \ ++ -expected-id 0x03731093 \ + -expected-id 0x03736093 + + jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477 diff --git a/meta-oe/recipes-devtools/openocd/openocd/0144-tcl-cpld-xilinx-xc7-remove-virtex-7-devices-with-ir-.patch b/meta-oe/recipes-devtools/openocd/openocd/0144-tcl-cpld-xilinx-xc7-remove-virtex-7-devices-with-ir-.patch new file mode 100644 index 000000000..b30673f4a --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0144-tcl-cpld-xilinx-xc7-remove-virtex-7-devices-with-ir-.patch @@ -0,0 +1,51 @@ +From ffd9638bdb04fb3021a20f78330c4692a2ebab6a Mon Sep 17 00:00:00 2001 +From: Daniel Anselmi +Date: Wed, 30 Nov 2022 04:05:44 +0100 +Subject: [PATCH] tcl: cpld/xilinx-xc7: remove virtex-7 devices with ir-length + > 6 + +They have an ir length of 22, 24 or 38 bit and different command codes. + +Change-Id: I488e8613f1c4d017e1590111f60b2725ec62964b +Signed-off-by: Daniel Anselmi +Reviewed-on: https://review.openocd.org/c/openocd/+/7387 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + tcl/cpld/xilinx-xc7.cfg | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/tcl/cpld/xilinx-xc7.cfg b/tcl/cpld/xilinx-xc7.cfg +index 22e0aea7f..91a07f9eb 100644 +--- a/tcl/cpld/xilinx-xc7.cfg ++++ b/tcl/cpld/xilinx-xc7.cfg +@@ -33,19 +33,21 @@ jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \ + -expected-id 0x03752093 \ + -expected-id 0x03751093 \ + -expected-id 0x03671093 \ +- -expected-id 0x036B3093 \ +- -expected-id 0x036B7093 \ +- -expected-id 0x036BB093 \ +- -expected-id 0x036BF093 \ + -expected-id 0x03667093 \ + -expected-id 0x03682093 \ + -expected-id 0x03687093 \ + -expected-id 0x03692093 \ + -expected-id 0x03691093 \ +- -expected-id 0x03696093 \ +- -expected-id 0x036D5093 \ +- -expected-id 0x036D9093 \ +- -expected-id 0x036DB093 ++ -expected-id 0x03696093 ++ ++#jtag newtap $_CHIPNAME tap -irlen 24 -ignore-version \ ++# -expected-id 0x036B3093 -expected-id 0x036B7093 \ ++# -expected-id 0x036BB093 -expected-id 0x036BF093 \ ++# -expected-id 0x036D5093 ++ ++#jtag newtap $_CHIPNAME tap -irlen 22 -ignore-version -expected-id 0x036D9093 ++ ++#jtag newtap $_CHIPNAME tap -irlen 38 -ignore-version -expected-id 0x036DB093 + + pld device virtex2 $_CHIPNAME.tap 1 + diff --git a/meta-oe/recipes-devtools/openocd/openocd/0145-doc-drop-resume-will-wait-5-seconds.patch b/meta-oe/recipes-devtools/openocd/openocd/0145-doc-drop-resume-will-wait-5-seconds.patch new file mode 100644 index 000000000..d7691f5ee --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0145-doc-drop-resume-will-wait-5-seconds.patch @@ -0,0 +1,36 @@ +From 0384fe5d596f42388f8b84d42959d899f29388ab Mon Sep 17 00:00:00 2001 +From: Tomas Vanek +Date: Tue, 4 Apr 2023 13:03:59 +0200 +Subject: [PATCH] doc: drop "resume will wait 5 seconds" + +Checkpatch-ignore: GIT_COMMIT_ID + +Waiting for running state was removed from handle_resume_command() +in commit a92d27afb073 ("very long and bad structured commit msg +without anything relevant to resume") around year 2008. +Update the doc accordingly. + +Silent checkpatch or we have to copy 10 or more lines +of the old commit msg. + +Signed-off-by: Tomas Vanek +Change-Id: I3296cb2c29cf80aeed63eddd8fbf352edec778c1 +Reviewed-on: https://review.openocd.org/c/openocd/+/7579 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + doc/openocd.texi | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index 67661845d..fe72cf5fa 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -8780,7 +8780,6 @@ power consumption (because the CPU is needlessly clocked). + @deffn {Command} {resume} [address] + Resume the target at its current code position, + or the optional @var{address} if it is provided. +-OpenOCD will wait 5 seconds for the target to resume. + @end deffn + + @deffn {Command} {step} [address] diff --git a/meta-oe/recipes-devtools/openocd/openocd/0146-target-espressif-add-application-tracing-functionali.patch b/meta-oe/recipes-devtools/openocd/openocd/0146-target-espressif-add-application-tracing-functionali.patch new file mode 100644 index 000000000..5ea321047 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0146-target-espressif-add-application-tracing-functionali.patch @@ -0,0 +1,2250 @@ +From 8d1dcf293a0cee71b264787c65749de3f6c4d8bc Mon Sep 17 00:00:00 2001 +From: Erhan Kurubas +Date: Thu, 25 Aug 2022 15:38:34 +0300 +Subject: [PATCH] target/espressif: add application tracing functionality over + JTAG + +This feature allows to transfer arbitrary data between host and +ESP32 via JTAG. + +The main use cases: + +1- Collecting application specific data +2- Lightweight logging to the host +3- System behaviour analysis with SEGGER SystemView +4- Source code coverage + +Signed-off-by: Erhan Kurubas +Change-Id: I95dee00ac22891fa326915a3fcac3c088cbb2afc +Reviewed-on: https://review.openocd.org/c/openocd/+/7163 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + doc/openocd.texi | 40 + + src/target/espressif/Makefile.am | 4 + + src/target/espressif/esp32.c | 5 + + src/target/espressif/esp32_apptrace.c | 1376 ++++++++++++++++++++ + src/target/espressif/esp32_apptrace.h | 126 ++ + src/target/espressif/esp32s2.c | 5 + + src/target/espressif/esp32s3.c | 5 + + src/target/espressif/esp_xtensa.c | 2 + + src/target/espressif/esp_xtensa.h | 2 + + src/target/espressif/esp_xtensa_apptrace.c | 497 +++++++ + src/target/espressif/esp_xtensa_apptrace.h | 37 + + 11 files changed, 2099 insertions(+) + create mode 100644 src/target/espressif/esp32_apptrace.c + create mode 100644 src/target/espressif/esp32_apptrace.h + create mode 100644 src/target/espressif/esp_xtensa_apptrace.c + create mode 100644 src/target/espressif/esp_xtensa_apptrace.h + +diff --git a/doc/openocd.texi b/doc/openocd.texi +index fe72cf5fa..4154e56b5 100644 +--- a/doc/openocd.texi ++++ b/doc/openocd.texi +@@ -11137,6 +11137,46 @@ Stop current trace as started by the tracestart command. + Dump trace memory to a file. + @end deffn + ++@section Espressif Specific Commands ++ ++@deffn {Command} {esp apptrace} (start [ [ [ [ []]]]]) ++Starts ++@uref{https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/app_trace.html#application-level-tracing-library, application level tracing}. ++Data will be stored to specified destination. Available destinations are: ++@itemize @bullet ++@item @code{file://} - Save trace logs into file. ++@item @code{tcp://:} - Send trace logs to tcp port on specified host. OpenOCD will act as a tcp client. ++@item @code{con:} - Print trace logs to the stdout. ++@end itemize ++Other parameters will be same for each destination. ++@itemize @bullet ++@item @code{poll_period} - trace data polling period in ms. ++@item @code{trace_size} - maximum trace data size. ++Tracing will be stopped automatically when that amount is reached. ++Use "-1" to disable the limitation. ++@item @code{stop_tmo} - Data reception timeout in ms. ++Tracing will be stopped automatically when no data is received within that period. ++@item @code{wait4halt} - if non-zero then wait for target to be halted before tracing start. ++@item @code{skip_size} - amount of tracing data to be skipped before writing it to destination. ++@end itemize ++@end deffn ++ ++@deffn {Command} {esp apptrace} (stop) ++Stops tracing started with above command. ++@end deffn ++ ++@deffn {Command} {esp apptrace} (status) ++Requests ongoing tracing status. ++@end deffn ++ ++@deffn {Command} {esp apptrace} (dump file://) ++Dumps tracing data from target buffer. It can be useful to dump the latest data ++buffered on target for post-mortem analysis. For example when target starts tracing automatically ++w/o OpenOCD command and keeps only the latest data window which fit into the buffer. ++@uref{https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/app_trace.html#application-level-tracing-library, application level tracing}. ++Data will be stored to specified destination. ++@end deffn ++ + @anchor{softwaredebugmessagesandtracing} + @section Software Debug Messages and Tracing + @cindex Linux-ARM DCC support +diff --git a/src/target/espressif/Makefile.am b/src/target/espressif/Makefile.am +index 8367a3881..c1759ed77 100644 +--- a/src/target/espressif/Makefile.am ++++ b/src/target/espressif/Makefile.am +@@ -8,6 +8,10 @@ noinst_LTLIBRARIES += %D%/libespressif.la + %D%/esp_xtensa_smp.h \ + %D%/esp_xtensa_semihosting.c \ + %D%/esp_xtensa_semihosting.h \ ++ %D%/esp_xtensa_apptrace.c \ ++ %D%/esp_xtensa_apptrace.h \ ++ %D%/esp32_apptrace.c \ ++ %D%/esp32_apptrace.h \ + %D%/esp32.c \ + %D%/esp32s2.c \ + %D%/esp32s3.c \ +diff --git a/src/target/espressif/esp32.c b/src/target/espressif/esp32.c +index 63055cf18..74bbe50bd 100644 +--- a/src/target/espressif/esp32.c ++++ b/src/target/espressif/esp32.c +@@ -440,6 +440,11 @@ static const struct command_registration esp32_command_handlers[] = { + { + .chain = esp_xtensa_smp_command_handlers, + }, ++ { ++ .name = "esp", ++ .usage = "", ++ .chain = esp32_apptrace_command_handlers, ++ }, + { + .name = "esp32", + .usage = "", +diff --git a/src/target/espressif/esp32_apptrace.c b/src/target/espressif/esp32_apptrace.c +new file mode 100644 +index 000000000..dfeb79401 +--- /dev/null ++++ b/src/target/espressif/esp32_apptrace.c +@@ -0,0 +1,1376 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++/*************************************************************************** ++ * ESP32xx application tracing module for OpenOCD * ++ * Copyright (C) 2017 Espressif Systems Ltd. * ++ ***************************************************************************/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#ifdef HAVE_ARPA_INET_H ++#include ++#endif ++ ++#ifdef HAVE_NETDB_H ++#include ++#endif ++ ++#ifndef _WIN32 ++#include ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "esp_xtensa.h" ++#include "esp_xtensa_smp.h" ++#include "esp_xtensa_apptrace.h" ++#include "esp32_apptrace.h" ++ ++#define ESP32_APPTRACE_USER_BLOCK_CORE(_v_) ((_v_) >> 15) ++#define ESP32_APPTRACE_USER_BLOCK_LEN(_v_) ((_v_) & ~BIT(15)) ++ ++#define ESP32_APPTRACE_USER_BLOCK_HDR_SZ 4 ++ ++#define ESP_APPTRACE_CMD_MODE_GEN 0 ++#define ESP_APPTRACE_CMD_MODE_SYSVIEW 1 ++#define ESP_APPTRACE_CMD_MODE_SYSVIEW_MCORE 2 ++#define ESP_APPTRACE_CMD_MODE_SYNC 3 ++ ++#define ESP32_APPTRACE_TGT_STATE_TMO 5000 ++#define ESP_APPTRACE_BLOCKS_POOL_SZ 10 ++ ++struct esp32_apptrace_dest_file_data { ++ int fout; ++}; ++ ++struct esp32_apptrace_dest_tcp_data { ++ int sockfd; ++}; ++ ++struct esp32_apptrace_target_state { ++ int running; ++ uint32_t block_id; ++ uint32_t data_len; ++}; ++ ++struct esp_apptrace_target2host_hdr { ++ uint16_t block_sz; ++ uint16_t wr_sz; ++}; ++#define APPTRACE_BLOCK_SIZE_OFFSET 0 ++#define APPTRACE_WR_SIZE_OFFSET 2 ++ ++struct esp32_apptrace_block { ++ struct list_head node; ++ uint8_t *data; ++ uint32_t data_len; ++}; ++ ++static int esp32_apptrace_data_processor(void *priv); ++static int esp32_apptrace_get_data_info(struct esp32_apptrace_cmd_ctx *ctx, ++ struct esp32_apptrace_target_state *target_state, ++ uint32_t *fired_target_num); ++static int esp32_apptrace_safe_halt_targets(struct esp32_apptrace_cmd_ctx *ctx, ++ struct esp32_apptrace_target_state *targets); ++static struct esp32_apptrace_block *esp32_apptrace_free_block_get(struct esp32_apptrace_cmd_ctx *ctx); ++static int esp32_apptrace_handle_trace_block(struct esp32_apptrace_cmd_ctx *ctx, ++ struct esp32_apptrace_block *block); ++ ++static const bool s_time_stats_enable = true; ++ ++/********************************************************************* ++* Trace destination API ++**********************************************************************/ ++ ++static int esp32_apptrace_file_dest_write(void *priv, uint8_t *data, int size) ++{ ++ struct esp32_apptrace_dest_file_data *dest_data = (struct esp32_apptrace_dest_file_data *)priv; ++ ++ int wr_sz = write(dest_data->fout, data, size); ++ if (wr_sz != size) { ++ LOG_ERROR("Failed to write %d bytes to out file (%d)! Written %d.", size, errno, wr_sz); ++ return ERROR_FAIL; ++ } ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_file_dest_cleanup(void *priv) ++{ ++ struct esp32_apptrace_dest_file_data *dest_data = (struct esp32_apptrace_dest_file_data *)priv; ++ ++ if (dest_data->fout > 0) ++ close(dest_data->fout); ++ free(dest_data); ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_file_dest_init(struct esp32_apptrace_dest *dest, const char *dest_name) ++{ ++ struct esp32_apptrace_dest_file_data *dest_data = calloc(1, sizeof(*dest_data)); ++ if (!dest_data) { ++ LOG_ERROR("Failed to alloc mem for file dest!"); ++ return ERROR_FAIL; ++ } ++ ++ LOG_INFO("Open file %s", dest_name); ++ dest_data->fout = open(dest_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); ++ if (dest_data->fout <= 0) { ++ LOG_ERROR("Failed to open file %s", dest_name); ++ free(dest_data); ++ return ERROR_FAIL; ++ } ++ ++ dest->priv = dest_data; ++ dest->write = esp32_apptrace_file_dest_write; ++ dest->clean = esp32_apptrace_file_dest_cleanup; ++ dest->log_progress = true; ++ ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_console_dest_write(void *priv, uint8_t *data, int size) ++{ ++ LOG_USER_N("%.*s", size, data); ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_console_dest_cleanup(void *priv) ++{ ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_console_dest_init(struct esp32_apptrace_dest *dest, const char *dest_name) ++{ ++ dest->priv = NULL; ++ dest->write = esp32_apptrace_console_dest_write; ++ dest->clean = esp32_apptrace_console_dest_cleanup; ++ dest->log_progress = false; ++ ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_tcp_dest_write(void *priv, uint8_t *data, int size) ++{ ++ struct esp32_apptrace_dest_tcp_data *dest_data = (struct esp32_apptrace_dest_tcp_data *)priv; ++ int wr_sz = write_socket(dest_data->sockfd, data, size); ++ if (wr_sz != size) { ++ LOG_ERROR("Failed to write %u bytes to out socket (%d)! Written %d.", size, errno, wr_sz); ++ return ERROR_FAIL; ++ } ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_tcp_dest_cleanup(void *priv) ++{ ++ struct esp32_apptrace_dest_tcp_data *dest_data = (struct esp32_apptrace_dest_tcp_data *)priv; ++ ++ if (dest_data->sockfd > 0) ++ close_socket(dest_data->sockfd); ++ free(dest_data); ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_tcp_dest_init(struct esp32_apptrace_dest *dest, const char *dest_name) ++{ ++ const char *port_sep = strchr(dest_name, ':'); ++ /* separator not found, or was the first or the last character */ ++ if (!port_sep || port_sep == dest_name || port_sep == dest_name + strlen(dest_name) - 1) { ++ LOG_ERROR("apptrace: Invalid connection URI, format should be tcp://host:port"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } ++ size_t hostname_len = port_sep - dest_name; ++ ++ char hostname[64] = { 0 }; ++ if (hostname_len >= sizeof(hostname)) { ++ LOG_ERROR("apptrace: Hostname too long"); ++ return ERROR_COMMAND_ARGUMENT_INVALID; ++ } ++ memcpy(hostname, dest_name, hostname_len); ++ ++ const char *port_str = port_sep + 1; ++ struct addrinfo *ai; ++ int flags = 0; ++#ifdef AI_NUMERICSERV ++ flags |= AI_NUMERICSERV; ++#endif /* AI_NUMERICSERV */ ++ struct addrinfo hint = { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = 0, ++ .ai_flags = flags ++ }; ++ int res = getaddrinfo(hostname, port_str, &hint, &ai); ++ if (res != 0) { ++ LOG_ERROR("apptrace: Failed to resolve host name: %s", hostname); ++ return ERROR_FAIL; ++ } ++ int sockfd = -1; ++ for (struct addrinfo *ai_it = ai; ai_it; ai_it = ai_it->ai_next) { ++ sockfd = socket(ai_it->ai_family, ai_it->ai_socktype, ai_it->ai_protocol); ++ if (sockfd < 0) { ++ LOG_DEBUG("apptrace: Failed to create socket (%d, %d, %d) (%s)", ++ ai_it->ai_family, ++ ai_it->ai_socktype, ++ ai_it->ai_protocol, ++ strerror(errno)); ++ continue; ++ } ++ ++ char cur_hostname[NI_MAXHOST]; ++ char cur_portname[NI_MAXSERV]; ++ res = ++ getnameinfo(ai_it->ai_addr, ai_it->ai_addrlen, cur_hostname, ++ sizeof(cur_hostname), ++ cur_portname, sizeof(cur_portname), ++ NI_NUMERICHOST | NI_NUMERICSERV); ++ if (res != 0) ++ continue; ++ ++ LOG_INFO("apptrace: Trying to connect to %s:%s", cur_hostname, cur_portname); ++ if (connect(sockfd, ai_it->ai_addr, ai_it->ai_addrlen) < 0) { ++ close_socket(sockfd); ++ sockfd = -1; ++ LOG_WARNING("apptrace: Connection failed (%s)", strerror(errno)); ++ continue; ++ } ++ break; ++ } ++ freeaddrinfo(ai); ++ if (sockfd < 0) { ++ LOG_ERROR("apptrace: Could not connect to %s:%s", hostname, port_str); ++ return ERROR_FAIL; ++ } ++ LOG_INFO("apptrace: Connected!"); ++ ++ struct esp32_apptrace_dest_tcp_data *dest_data = calloc(1, sizeof(struct esp32_apptrace_dest_tcp_data)); ++ if (!dest_data) { ++ LOG_ERROR("apptrace: Failed to alloc mem for tcp dest!"); ++ close_socket(sockfd); ++ return ERROR_FAIL; ++ } ++ ++ dest_data->sockfd = sockfd; ++ dest->priv = dest_data; ++ dest->write = esp32_apptrace_tcp_dest_write; ++ dest->clean = esp32_apptrace_tcp_dest_cleanup; ++ dest->log_progress = true; ++ ++ return ERROR_OK; ++} ++ ++int esp32_apptrace_dest_init(struct esp32_apptrace_dest dest[], const char *dest_paths[], unsigned int max_dests) ++{ ++ int res; ++ unsigned int i; ++ ++ for (i = 0; i < max_dests; i++) { ++ if (strncmp(dest_paths[i], "file://", 7) == 0) ++ res = esp32_apptrace_file_dest_init(&dest[i], &dest_paths[i][7]); ++ else if (strncmp(dest_paths[i], "con:", 4) == 0) ++ res = esp32_apptrace_console_dest_init(&dest[i], NULL); ++ else if (strncmp(dest_paths[i], "tcp://", 6) == 0) ++ res = esp32_apptrace_tcp_dest_init(&dest[i], &dest_paths[i][6]); ++ else ++ break; ++ ++ if (res != ERROR_OK) { ++ LOG_ERROR("apptrace: Failed to init trace data destination '%s'!", dest_paths[i]); ++ return 0; ++ } ++ } ++ ++ return i; ++} ++ ++int esp32_apptrace_dest_cleanup(struct esp32_apptrace_dest dest[], unsigned int max_dests) ++{ ++ for (unsigned int i = 0; i < max_dests; i++) { ++ if (dest[i].clean && dest[i].priv) { ++ int res = dest[i].clean(dest[i].priv); ++ dest[i].priv = NULL; ++ return res; ++ } ++ } ++ return ERROR_OK; ++} ++ ++/********************************************************************* ++* Trace data blocks management API ++**********************************************************************/ ++static void esp32_apptrace_blocks_pool_cleanup(struct esp32_apptrace_cmd_ctx *ctx) ++{ ++ struct esp32_apptrace_block *cur; ++ struct list_head *head = &ctx->free_trace_blocks; ++ struct list_head *tmp, *pos; ++ ++ list_for_each_safe(pos, tmp, head) { ++ cur = list_entry(pos, struct esp32_apptrace_block, node); ++ if (cur) { ++ list_del(&cur->node); ++ free(cur->data); ++ free(cur); ++ } ++ } ++ ++ head = &ctx->ready_trace_blocks; ++ ++ list_for_each_safe(pos, tmp, head) { ++ cur = list_entry(pos, struct esp32_apptrace_block, node); ++ if (cur) { ++ list_del(&cur->node); ++ free(cur->data); ++ free(cur); ++ } ++ } ++} ++ ++struct esp32_apptrace_block *esp32_apptrace_free_block_get(struct esp32_apptrace_cmd_ctx *ctx) ++{ ++ struct esp32_apptrace_block *block = NULL; ++ ++ if (!list_empty(&ctx->free_trace_blocks)) { ++ /*get first */ ++ block = list_first_entry(&ctx->free_trace_blocks, struct esp32_apptrace_block, node); ++ list_del(&block->node); ++ } ++ ++ return block; ++} ++ ++static int esp32_apptrace_ready_block_put(struct esp32_apptrace_cmd_ctx *ctx, struct esp32_apptrace_block *block) ++{ ++ LOG_DEBUG("esp32_apptrace_ready_block_put"); ++ /* add to ready blocks list */ ++ INIT_LIST_HEAD(&block->node); ++ list_add(&block->node, &ctx->ready_trace_blocks); ++ ++ return ERROR_OK; ++} ++ ++static struct esp32_apptrace_block *esp32_apptrace_ready_block_get(struct esp32_apptrace_cmd_ctx *ctx) ++{ ++ struct esp32_apptrace_block *block = NULL; ++ ++ if (!list_empty(&ctx->ready_trace_blocks)) { ++ struct list_head *head = &ctx->ready_trace_blocks; ++ struct list_head *tmp, *pos; ++ ++ list_for_each_safe(pos, tmp, head) { ++ block = list_entry(pos, struct esp32_apptrace_block, node); ++ } ++ /* remove it from ready list */ ++ list_del(&block->node); ++ } ++ ++ return block; ++} ++ ++static int esp32_apptrace_block_free(struct esp32_apptrace_cmd_ctx *ctx, struct esp32_apptrace_block *block) ++{ ++ /* add to free blocks list */ ++ INIT_LIST_HEAD(&block->node); ++ list_add(&block->node, &ctx->free_trace_blocks); ++ ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_wait_tracing_finished(struct esp32_apptrace_cmd_ctx *ctx) ++{ ++ int64_t timeout = timeval_ms() + (LOG_LEVEL_IS(LOG_LVL_DEBUG) ? 70000 : 5000); ++ while (!list_empty(&ctx->ready_trace_blocks)) { ++ alive_sleep(100); ++ if (timeval_ms() >= timeout) { ++ LOG_ERROR("Failed to wait for pended trace blocks!"); ++ return ERROR_FAIL; ++ } ++ } ++ /* signal timer callback to stop */ ++ ctx->running = 0; ++ target_unregister_timer_callback(esp32_apptrace_data_processor, ctx); ++ return ERROR_OK; ++} ++ ++/********************************************************************* ++* Trace commands ++**********************************************************************/ ++ ++int esp32_apptrace_cmd_ctx_init(struct esp32_apptrace_cmd_ctx *cmd_ctx, struct command_invocation *cmd, int mode) ++{ ++ struct target *target = get_current_target(CMD_CTX); ++ ++ memset(cmd_ctx, 0, sizeof(struct esp32_apptrace_cmd_ctx)); ++ cmd_ctx->target = target; ++ cmd_ctx->mode = mode; ++ cmd_ctx->target_state = target->state; ++ cmd_ctx->cmd = cmd; ++ ++ if (target->smp) { ++ struct target_list *head; ++ struct target *curr; ++ unsigned int i = 0; ++ cmd_ctx->cores_num = 0; ++ foreach_smp_target(head, target->smp_targets) { ++ curr = head->target; ++ if (i == ESP32_APPTRACE_MAX_CORES_NUM) { ++ command_print(cmd, "Too many cores configured! Max %d cores are supported.", ++ ESP32_APPTRACE_MAX_CORES_NUM); ++ return ERROR_FAIL; ++ } ++ if (!target_was_examined(curr)) ++ continue; ++ cmd_ctx->cores_num++; ++ cmd_ctx->cpus[i++] = curr; ++ } ++ } else { ++ cmd_ctx->cores_num = 1; ++ cmd_ctx->cpus[0] = target; ++ } ++ /* some relies on ESP32_APPTRACE_MAX_CORES_NUM ++ * TODO: remove that dependency */ ++ assert(cmd_ctx->cores_num <= ESP32_APPTRACE_MAX_CORES_NUM && "Too many cores number!"); ++ ++ struct xtensa *xtensa = target->arch_info; ++ if (xtensa->common_magic == XTENSA_COMMON_MAGIC) { ++ cmd_ctx->hw = target_to_esp_xtensa(target)->apptrace.hw; ++ } else { /* TODO: riscv is not supported yet */ ++ command_print(cmd, "Unsupported target arch 0x%X", xtensa->common_magic); ++ return ERROR_FAIL; ++ } ++ ++ cmd_ctx->max_trace_block_sz = cmd_ctx->hw->max_block_size_get(cmd_ctx->cpus[0]); ++ if (cmd_ctx->max_trace_block_sz == 0) { ++ command_print(cmd, "Failed to get max trace block size!"); ++ return ERROR_FAIL; ++ } ++ LOG_INFO("Total trace memory: %" PRIu32 " bytes", cmd_ctx->max_trace_block_sz); ++ ++ INIT_LIST_HEAD(&cmd_ctx->ready_trace_blocks); ++ INIT_LIST_HEAD(&cmd_ctx->free_trace_blocks); ++ for (unsigned int i = 0; i < ESP_APPTRACE_BLOCKS_POOL_SZ; i++) { ++ struct esp32_apptrace_block *block = calloc(1, sizeof(struct esp32_apptrace_block)); ++ if (!block) { ++ command_print(cmd, "Failed to alloc trace buffer entry!"); ++ esp32_apptrace_blocks_pool_cleanup(cmd_ctx); ++ return ERROR_FAIL; ++ } ++ block->data = malloc(cmd_ctx->max_trace_block_sz); ++ if (!block->data) { ++ free(block); ++ command_print(cmd, "Failed to alloc trace buffer %" PRIu32 " bytes!", cmd_ctx->max_trace_block_sz); ++ esp32_apptrace_blocks_pool_cleanup(cmd_ctx); ++ return ERROR_FAIL; ++ } ++ INIT_LIST_HEAD(&block->node); ++ list_add(&block->node, &cmd_ctx->free_trace_blocks); ++ } ++ ++ cmd_ctx->running = 1; ++ if (cmd_ctx->mode != ESP_APPTRACE_CMD_MODE_SYNC) { ++ int res = target_register_timer_callback(esp32_apptrace_data_processor, ++ 0, ++ TARGET_TIMER_TYPE_PERIODIC, ++ cmd_ctx); ++ if (res != ERROR_OK) { ++ command_print(cmd, "Failed to start trace data timer callback (%d)!", res); ++ esp32_apptrace_blocks_pool_cleanup(cmd_ctx); ++ return ERROR_FAIL; ++ } ++ } ++ ++ if (s_time_stats_enable) { ++ cmd_ctx->stats.min_blk_read_time = 1000000.0; ++ cmd_ctx->stats.min_blk_proc_time = 1000000.0; ++ } ++ if (duration_start(&cmd_ctx->idle_time) != 0) { ++ command_print(cmd, "Failed to start idle time measurement!"); ++ esp32_apptrace_cmd_ctx_cleanup(cmd_ctx); ++ return ERROR_FAIL; ++ } ++ ++ return ERROR_OK; ++} ++ ++int esp32_apptrace_cmd_ctx_cleanup(struct esp32_apptrace_cmd_ctx *cmd_ctx) ++{ ++ esp32_apptrace_blocks_pool_cleanup(cmd_ctx); ++ return ERROR_OK; ++} ++ ++#define ESP32_APPTRACE_CMD_NUM_ARG_CHECK(_cmd_, _arg_, _start_, _end_) \ ++ do { \ ++ if ((_arg_) == 0 && (_start_) == (_end_)) { \ ++ command_print(_cmd_, "Invalid '" # _arg_ "' arg!"); \ ++ return; \ ++ } \ ++ } while (0) ++ ++void esp32_apptrace_cmd_args_parse(struct esp32_apptrace_cmd_ctx *cmd_ctx, ++ struct esp32_apptrace_cmd_data *cmd_data, ++ const char **argv, ++ int argc) ++{ ++ char *end; ++ ++ cmd_data->poll_period = strtoul(argv[0], &end, 10); ++ ESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, cmd_data->poll_period, argv[0], end); ++ if (argc > 1) { ++ cmd_data->max_len = strtoul(argv[1], &end, 10); ++ ESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, cmd_data->max_len, argv[1], end); ++ if (argc > 2) { ++ int32_t tmo = strtol(argv[2], &end, 10); ++ ESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, tmo, argv[2], end); ++ cmd_ctx->stop_tmo = 1.0 * tmo; ++ if (argc > 3) { ++ cmd_data->wait4halt = strtoul(argv[3], &end, 10); ++ ESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, cmd_data->wait4halt, argv[3], end); ++ if (argc > 4) { ++ cmd_data->skip_len = strtoul(argv[4], &end, 10); ++ ESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, cmd_data->skip_len, argv[4], end); ++ } ++ } ++ } ++ } ++} ++ ++static int esp32_apptrace_core_id_get(struct target *target, uint8_t *hdr_buf) ++{ ++ return ESP32_APPTRACE_USER_BLOCK_CORE(target_buffer_get_u16(target, hdr_buf + APPTRACE_BLOCK_SIZE_OFFSET)); ++} ++ ++static uint32_t esp32_apptrace_usr_block_len_get(struct target *target, uint8_t *hdr_buf, uint32_t *wr_len) ++{ ++ *wr_len = ESP32_APPTRACE_USER_BLOCK_LEN(target_buffer_get_u16(target, hdr_buf + APPTRACE_WR_SIZE_OFFSET)); ++ return ESP32_APPTRACE_USER_BLOCK_LEN(target_buffer_get_u16(target, hdr_buf + APPTRACE_BLOCK_SIZE_OFFSET)); ++} ++ ++static int esp32_apptrace_cmd_init(struct esp32_apptrace_cmd_ctx *cmd_ctx, ++ struct command_invocation *cmd, ++ int mode, ++ const char **argv, ++ int argc) ++{ ++ struct esp32_apptrace_cmd_data *cmd_data; ++ ++ if (argc < 1) { ++ command_print(cmd, "Not enough args! Need trace data destination!"); ++ return ERROR_FAIL; ++ } ++ ++ int res = esp32_apptrace_cmd_ctx_init(cmd_ctx, cmd, mode); ++ if (res != ERROR_OK) ++ return res; ++ ++ cmd_data = calloc(1, sizeof(*cmd_data)); ++ assert(cmd_data && "No memory for command data!"); ++ cmd_ctx->cmd_priv = cmd_data; ++ ++ /*outfile1 [poll_period [trace_size [stop_tmo [wait4halt [skip_size]]]]] */ ++ res = esp32_apptrace_dest_init(&cmd_data->data_dest, argv, 1); ++ if (res != 1) { /* only one destination needs to be initialized */ ++ command_print(cmd, "Wrong args! Needs a trace data destination!"); ++ free(cmd_data); ++ goto on_error; ++ } ++ cmd_ctx->stop_tmo = -1.0; /* infinite */ ++ cmd_data->max_len = UINT32_MAX; ++ cmd_data->poll_period = 0 /*ms*/; ++ if (argc > 1) ++ /* parse remaining args */ ++ esp32_apptrace_cmd_args_parse(cmd_ctx, cmd_data, &argv[1], argc - 1); ++ ++ LOG_USER("App trace params: from %d cores, size %" PRId32 " bytes, stop_tmo %g s, poll period %" PRId32 ++ " ms, wait_rst %d, skip %" PRId32 " bytes", cmd_ctx->cores_num, ++ cmd_data->max_len, ++ cmd_ctx->stop_tmo, ++ cmd_data->poll_period, ++ cmd_data->wait4halt, ++ cmd_data->skip_len); ++ ++ cmd_ctx->trace_format.hdr_sz = ESP32_APPTRACE_USER_BLOCK_HDR_SZ; ++ cmd_ctx->trace_format.core_id_get = esp32_apptrace_core_id_get; ++ cmd_ctx->trace_format.usr_block_len_get = esp32_apptrace_usr_block_len_get; ++ return ERROR_OK; ++on_error: ++ command_print(cmd, "Not enough args! Need %d trace data destinations!", cmd_ctx->cores_num); ++ cmd_ctx->running = 0; ++ esp32_apptrace_cmd_ctx_cleanup(cmd_ctx); ++ return res; ++} ++ ++static int esp32_apptrace_cmd_cleanup(struct esp32_apptrace_cmd_ctx *cmd_ctx) ++{ ++ struct esp32_apptrace_cmd_data *cmd_data = cmd_ctx->cmd_priv; ++ ++ esp32_apptrace_dest_cleanup(&cmd_data->data_dest, 1); ++ free(cmd_data); ++ cmd_ctx->cmd_priv = NULL; ++ esp32_apptrace_cmd_ctx_cleanup(cmd_ctx); ++ return ERROR_OK; ++} ++ ++static void esp32_apptrace_print_stats(struct esp32_apptrace_cmd_ctx *ctx) ++{ ++ struct esp32_apptrace_cmd_data *cmd_data = ctx->cmd_priv; ++ uint32_t trace_sz = 0; ++ ++ if (cmd_data) ++ trace_sz = ctx->tot_len > cmd_data->skip_len ? ctx->tot_len - cmd_data->skip_len : 0; ++ LOG_USER("Tracing is %s. Size is %" PRId32 " of %" PRId32 " @ %f (%f) KiB/s", ++ !ctx->running ? "STOPPED" : "RUNNING", ++ trace_sz, ++ cmd_data ? cmd_data->max_len : 0, ++ duration_kbps(&ctx->read_time, ctx->tot_len), ++ duration_kbps(&ctx->read_time, ctx->raw_tot_len)); ++ LOG_USER("Data: blocks incomplete %" PRId32 ", lost bytes: %" PRId32, ++ ctx->stats.incompl_blocks, ++ ctx->stats.lost_bytes); ++ if (s_time_stats_enable) { ++ LOG_USER("Block read time [%f..%f] ms", ++ 1000 * ctx->stats.min_blk_read_time, ++ 1000 * ctx->stats.max_blk_read_time); ++ LOG_USER("Block proc time [%f..%f] ms", ++ 1000 * ctx->stats.min_blk_proc_time, ++ 1000 * ctx->stats.max_blk_proc_time); ++ } ++} ++ ++static int esp32_apptrace_wait4halt(struct esp32_apptrace_cmd_ctx *ctx, struct target *target) ++{ ++ LOG_USER("Wait for halt..."); ++ while (!openocd_is_shutdown_pending()) { ++ int res = target_poll(target); ++ if (res != ERROR_OK) ++ return res; ++ if (target->state == TARGET_HALTED) { ++ LOG_USER("%s: HALTED", target->cmd_name); ++ break; ++ } ++ alive_sleep(500); ++ } ++ return ERROR_OK; ++} ++ ++int esp32_apptrace_safe_halt_targets(struct esp32_apptrace_cmd_ctx *ctx, ++ struct esp32_apptrace_target_state *targets) ++{ ++ int res = ERROR_OK; ++ ++ memset(targets, 0, ctx->cores_num * sizeof(struct esp32_apptrace_target_state)); ++ /* halt all CPUs */ ++ LOG_DEBUG("Halt all targets!"); ++ for (unsigned int k = 0; k < ctx->cores_num; k++) { ++ if (!target_was_examined(ctx->cpus[k])) ++ continue; ++ if (ctx->cpus[k]->state == TARGET_HALTED) ++ continue; ++ res = target_halt(ctx->cpus[k]); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to halt target (%d)!", res); ++ return res; ++ } ++ res = target_wait_state(ctx->cpus[k], TARGET_HALTED, ESP32_APPTRACE_TGT_STATE_TMO); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to wait halt target %s / %d (%d)!", ++ target_name(ctx->cpus[k]), ++ ctx->cpus[k]->state, ++ res); ++ return res; ++ } ++ } ++ /* read current block statuses from CPUs */ ++ LOG_DEBUG("Read current block statuses"); ++ for (unsigned int k = 0; k < ctx->cores_num; k++) { ++ uint32_t stat; ++ res = ctx->hw->status_reg_read(ctx->cpus[k], &stat); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to read trace status (%d)!", res); ++ return res; ++ } ++ /* check if some CPU stopped inside tracing regs update critical section */ ++ if (stat) { ++ if (ctx->hw->leave_trace_crit_section_start) { ++ res = ctx->hw->leave_trace_crit_section_start(ctx->cpus[k]); ++ if (res != ERROR_OK) ++ return res; ++ } ++ uint32_t bp_addr = stat; ++ res = breakpoint_add(ctx->cpus[k], bp_addr, 1, BKPT_HARD); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to set breakpoint (%d)!", res); ++ return res; ++ } ++ while (stat) { ++ /* allow this CPU to leave ERI write critical section */ ++ res = target_resume(ctx->cpus[k], 1, 0, 1, 0); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to resume target (%d)!", res); ++ breakpoint_remove(ctx->cpus[k], bp_addr); ++ return res; ++ } ++ /* wait for CPU to be halted on BP */ ++ enum target_debug_reason debug_reason = DBG_REASON_UNDEFINED; ++ while (debug_reason != DBG_REASON_BREAKPOINT) { ++ res = target_wait_state(ctx->cpus[k], TARGET_HALTED, ++ ESP32_APPTRACE_TGT_STATE_TMO); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to wait halt on bp (%d)!", res); ++ breakpoint_remove(ctx->cpus[k], bp_addr); ++ return res; ++ } ++ debug_reason = ctx->cpus[k]->debug_reason; ++ } ++ res = ctx->hw->status_reg_read(ctx->cpus[k], &stat); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to read trace status (%d)!", res); ++ breakpoint_remove(ctx->cpus[k], bp_addr); ++ return res; ++ } ++ } ++ breakpoint_remove(ctx->cpus[k], bp_addr); ++ if (ctx->hw->leave_trace_crit_section_stop) { ++ res = ctx->hw->leave_trace_crit_section_stop(ctx->cpus[k]); ++ if (res != ERROR_OK) ++ return res; ++ } ++ } ++ res = ctx->hw->data_len_read(ctx->cpus[k], &targets[k].block_id, &targets[k].data_len); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to read trace status (%d)!", res); ++ return res; ++ } ++ } ++ ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_connect_targets(struct esp32_apptrace_cmd_ctx *ctx, ++ bool conn, ++ bool resume_target) ++{ ++ struct esp32_apptrace_target_state target_to_connect[ESP32_APPTRACE_MAX_CORES_NUM]; ++ ++ if (conn) ++ LOG_USER("Connect targets..."); ++ else ++ LOG_USER("Disconnect targets..."); ++ ++ int res = esp32_apptrace_safe_halt_targets(ctx, target_to_connect); ++ if (res != ERROR_OK) { ++ command_print(ctx->cmd, "Failed to halt targets (%d)!", res); ++ return res; ++ } ++ if (ctx->cores_num > 1) { ++ /* set block ids to the highest value */ ++ uint32_t max_id = 0; ++ for (unsigned int k = 0; k < ctx->cores_num; k++) { ++ if (target_to_connect[k].block_id > max_id) ++ max_id = target_to_connect[k].block_id; ++ } ++ for (unsigned int k = 0; k < ctx->cores_num; k++) ++ target_to_connect[k].block_id = max_id; ++ } ++ for (unsigned int k = 0; k < ctx->cores_num; k++) { ++ /* update host connected status */ ++ res = ctx->hw->ctrl_reg_write(ctx->cpus[k], ++ target_to_connect[k].block_id, ++ 0 /*ack target data*/, ++ conn, ++ false /*no host data*/); ++ if (res != ERROR_OK) { ++ command_print(ctx->cmd, "Failed to read trace status (%d)!", res); ++ return res; ++ } ++ } ++ if (resume_target) { ++ LOG_DEBUG("Resume targets"); ++ bool smp_resumed = false; ++ for (unsigned int k = 0; k < ctx->cores_num; k++) { ++ if (smp_resumed && ctx->cpus[k]->smp) { ++ /* in SMP mode we need to call target_resume for one core only */ ++ continue; ++ } ++ res = target_resume(ctx->cpus[k], 1, 0, 1, 0); ++ if (res != ERROR_OK) { ++ command_print(ctx->cmd, "Failed to resume target (%d)!", res); ++ return res; ++ } ++ if (ctx->cpus[k]->smp) ++ smp_resumed = true; ++ } ++ } ++ if (conn) ++ LOG_INFO("Targets connected."); ++ else ++ LOG_INFO("Targets disconnected."); ++ return ERROR_OK; ++} ++ ++int esp_apptrace_usr_block_write(const struct esp32_apptrace_hw *hw, struct target *target, ++ uint32_t block_id, ++ const uint8_t *data, ++ uint32_t size) ++{ ++ struct esp_apptrace_host2target_hdr hdr = { .block_sz = size }; ++ uint32_t buf_sz[2] = { sizeof(hdr), size }; ++ const uint8_t *bufs[2] = { (const uint8_t *)&hdr, data }; ++ ++ if (size > hw->usr_block_max_size_get(target)) { ++ LOG_ERROR("Too large user block %" PRId32, size); ++ return ERROR_FAIL; ++ } ++ ++ return hw->buffs_write(target, ++ ARRAY_SIZE(buf_sz), ++ buf_sz, ++ bufs, ++ block_id, ++ true /*ack target data*/, ++ true /*host data*/); ++} ++ ++static uint32_t esp32_apptrace_usr_block_check(struct esp32_apptrace_cmd_ctx *ctx, uint8_t *hdr_buf) ++{ ++ uint32_t wr_len = 0; ++ uint32_t usr_len = ctx->trace_format.usr_block_len_get(ctx->target, hdr_buf, &wr_len); ++ if (usr_len != wr_len) { ++ LOG_ERROR("Incomplete block sz %" PRId32 ", wr %" PRId32, usr_len, wr_len); ++ ctx->stats.incompl_blocks++; ++ ctx->stats.lost_bytes += usr_len - wr_len; ++ } ++ return usr_len; ++} ++ ++int esp32_apptrace_get_data_info(struct esp32_apptrace_cmd_ctx *ctx, ++ struct esp32_apptrace_target_state *target_state, ++ uint32_t *fired_target_num) ++{ ++ if (fired_target_num) ++ *fired_target_num = UINT32_MAX; ++ ++ for (unsigned int i = 0; i < ctx->cores_num; i++) { ++ int res = ctx->hw->data_len_read(ctx->cpus[i], &target_state[i].block_id, &target_state[i].data_len); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to read data len on (%s)!", target_name(ctx->cpus[i])); ++ return res; ++ } ++ if (target_state[i].data_len) { ++ LOG_TARGET_DEBUG(ctx->cpus[i], "Block %" PRId32 ", len %" PRId32 " bytes on fired", ++ target_state[i].block_id, target_state[i].data_len); ++ if (fired_target_num) ++ *fired_target_num = i; ++ break; ++ } ++ } ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_process_data(struct esp32_apptrace_cmd_ctx *ctx, ++ unsigned int core_id, ++ uint8_t *data, ++ uint32_t data_len) ++{ ++ struct esp32_apptrace_cmd_data *cmd_data = ctx->cmd_priv; ++ ++ LOG_DEBUG("Got block %" PRId32 " bytes [%x %x...%x %x]", data_len, data[12], data[13], ++ data[data_len - 2], data[data_len - 1]); ++ if (ctx->tot_len + data_len > cmd_data->skip_len) { ++ uint32_t wr_idx = 0, wr_chunk_len = data_len; ++ if (ctx->tot_len < cmd_data->skip_len) { ++ wr_chunk_len = (ctx->tot_len + wr_chunk_len) - cmd_data->skip_len; ++ wr_idx = cmd_data->skip_len - ctx->tot_len; ++ } ++ if (ctx->tot_len + wr_chunk_len > cmd_data->max_len) ++ wr_chunk_len -= (ctx->tot_len + wr_chunk_len - cmd_data->skip_len) - cmd_data->max_len; ++ if (wr_chunk_len > 0) { ++ int res = cmd_data->data_dest.write(cmd_data->data_dest.priv, data + wr_idx, wr_chunk_len); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to write %" PRId32 " bytes to dest 0!", data_len); ++ return res; ++ } ++ } ++ ctx->tot_len += wr_chunk_len; ++ } else { ++ ctx->tot_len += data_len; ++ } ++ ++ if (cmd_data->data_dest.log_progress) ++ LOG_USER("%" PRId32 " ", ctx->tot_len); ++ /* check for stop condition */ ++ if (ctx->tot_len > cmd_data->skip_len && (ctx->tot_len - cmd_data->skip_len >= cmd_data->max_len)) { ++ ctx->running = 0; ++ if (duration_measure(&ctx->read_time) != 0) { ++ LOG_ERROR("Failed to stop trace read time measure!"); ++ return ERROR_FAIL; ++ } ++ } ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_handle_trace_block(struct esp32_apptrace_cmd_ctx *ctx, ++ struct esp32_apptrace_block *block) ++{ ++ uint32_t processed = 0; ++ uint32_t hdr_sz = ctx->trace_format.hdr_sz; ++ ++ LOG_DEBUG("Got block %" PRId32 " bytes", block->data_len); ++ /* process user blocks one by one */ ++ while (processed < block->data_len) { ++ LOG_DEBUG("Process usr block %" PRId32 "/%" PRId32, processed, block->data_len); ++ /* process user block */ ++ uint32_t usr_len = esp32_apptrace_usr_block_check(ctx, block->data + processed); ++ int core_id = ctx->trace_format.core_id_get(ctx->target, block->data + processed); ++ /* process user data */ ++ int res = ctx->process_data(ctx, core_id, block->data + processed + hdr_sz, usr_len); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to process %" PRId32 " bytes!", usr_len); ++ return res; ++ } ++ processed += usr_len + hdr_sz; ++ } ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_data_processor(void *priv) ++{ ++ struct esp32_apptrace_cmd_ctx *ctx = (struct esp32_apptrace_cmd_ctx *)priv; ++ ++ if (!ctx->running) ++ return ERROR_OK; ++ ++ struct esp32_apptrace_block *block = esp32_apptrace_ready_block_get(ctx); ++ if (!block) ++ return ERROR_OK; ++ ++ int res = esp32_apptrace_handle_trace_block(ctx, block); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to process trace block %" PRId32 " bytes!", block->data_len); ++ return res; ++ } ++ res = esp32_apptrace_block_free(ctx, block); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to free ready block!"); ++ return res; ++ } ++ ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_check_connection(struct esp32_apptrace_cmd_ctx *ctx) ++{ ++ if (!ctx) ++ return ERROR_FAIL; ++ ++ unsigned int busy_target_num = 0; ++ ++ for (unsigned int i = 0; i < ctx->cores_num; i++) { ++ bool conn = true; ++ int res = ctx->hw->ctrl_reg_read(ctx->cpus[i], NULL, NULL, &conn); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to read apptrace control reg for cpu(%d) res(%d)!", i, res); ++ return res; ++ } ++ if (!conn) { ++ uint32_t stat = 0; ++ LOG_TARGET_WARNING(ctx->cpus[i], "apptrace connection is lost. Re-connect."); ++ res = ctx->hw->status_reg_read(ctx->cpus[i], &stat); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to read trace status (%d)!", res); ++ return res; ++ } ++ if (stat) { ++ LOG_TARGET_WARNING(ctx->cpus[i], "in critical state. Retry in next poll"); ++ if (++busy_target_num == ctx->cores_num) { ++ LOG_WARNING("No available core"); ++ return ERROR_WAIT; ++ } ++ continue; ++ } ++ res = ctx->hw->ctrl_reg_write(ctx->cpus[i], ++ 0, ++ 0, ++ true /*host connected*/, ++ false /*no host data*/); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to write apptrace control reg for cpu(%d) res(%d)!", i, res); ++ return res; ++ } ++ if (ctx->stop_tmo != -1.0) { ++ /* re-start idle time measurement */ ++ if (duration_start(&ctx->idle_time) != 0) { ++ LOG_ERROR("Failed to re-start idle time measure!"); ++ return ERROR_FAIL; ++ } ++ } ++ } ++ } ++ ++ return ERROR_OK; ++} ++ ++static int esp32_apptrace_poll(void *priv) ++{ ++ struct esp32_apptrace_cmd_ctx *ctx = (struct esp32_apptrace_cmd_ctx *)priv; ++ int res; ++ uint32_t fired_target_num = 0; ++ struct esp32_apptrace_target_state target_state[ESP32_APPTRACE_MAX_CORES_NUM]; ++ struct duration blk_proc_time; ++ ++ if (!ctx->running) { ++ if (ctx->auto_clean) ++ ctx->auto_clean(ctx); ++ return ERROR_FAIL; ++ } ++ ++ /* Check for connection is alive.For some reason target and therefore host_connected flag ++ * might have been reset */ ++ res = esp32_apptrace_check_connection(ctx); ++ if (res != ERROR_OK) { ++ if (res != ERROR_WAIT) ++ ctx->running = 0; ++ return res; ++ } ++ ++ /* check for data from target */ ++ res = esp32_apptrace_get_data_info(ctx, target_state, &fired_target_num); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to read data len!"); ++ return res; ++ } ++ /* LOG_DEBUG("Block %d (%d bytes) on target (%s)!", target_state[0].block_id, ++ * target_state[0].data_len, target_name(ctx->cpus[0])); */ ++ if (fired_target_num == UINT32_MAX) { ++ /* no data has been received, but block could be switched due to the data transferred ++ * from host to target */ ++ if (ctx->cores_num > 1) { ++ uint32_t max_block_id = 0, min_block_id = ctx->hw->max_block_id; ++ /* find maximum block ID and set the same ID in control reg for both cores ++ * */ ++ for (unsigned int i = 0; i < ctx->cores_num; i++) { ++ if (max_block_id < target_state[i].block_id) ++ max_block_id = target_state[i].block_id; ++ if (min_block_id > target_state[i].block_id) ++ min_block_id = target_state[i].block_id; ++ } ++ /* handle block ID overflow */ ++ if (max_block_id == ctx->hw->max_block_id && min_block_id == 0) ++ max_block_id = 0; ++ for (unsigned int i = 0; i < ctx->cores_num; i++) { ++ if (max_block_id != target_state[i].block_id) { ++ LOG_TARGET_DEBUG(ctx->cpus[i], "Ack empty block %" PRId32 "!", max_block_id); ++ res = ctx->hw->ctrl_reg_write(ctx->cpus[i], ++ max_block_id, ++ 0 /*all read*/, ++ true /*host connected*/, ++ false /*no host data*/); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_TARGET_ERROR(ctx->cpus[i], "Failed to ack empty data block!"); ++ return res; ++ } ++ } ++ } ++ ctx->last_blk_id = max_block_id; ++ } ++ if (ctx->stop_tmo != -1.0) { ++ if (duration_measure(&ctx->idle_time) != 0) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to measure idle time!"); ++ return ERROR_FAIL; ++ } ++ if (duration_elapsed(&ctx->idle_time) >= ctx->stop_tmo) { ++ ctx->running = 0; ++ LOG_ERROR("Data timeout!"); ++ return ERROR_FAIL; ++ } ++ } ++ return ERROR_OK;/* no data */ ++ } ++ /* sanity check */ ++ if (target_state[fired_target_num].data_len > ctx->max_trace_block_sz) { ++ ctx->running = 0; ++ LOG_ERROR("Too large block size %" PRId32 "!", target_state[fired_target_num].data_len); ++ return ERROR_FAIL; ++ } ++ if (ctx->tot_len == 0) { ++ if (duration_start(&ctx->read_time) != 0) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to start trace read time measurement!"); ++ return ERROR_FAIL; ++ } ++ } ++ struct esp32_apptrace_block *block = esp32_apptrace_free_block_get(ctx); ++ if (!block) { ++ ctx->running = 0; ++ LOG_TARGET_ERROR(ctx->cpus[fired_target_num], "Failed to get free block for data!"); ++ return ERROR_FAIL; ++ } ++ if (s_time_stats_enable) { ++ /* read block */ ++ if (duration_start(&blk_proc_time) != 0) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to start block read time measurement!"); ++ return ERROR_FAIL; ++ } ++ } ++ res = ++ ctx->hw->data_read(ctx->cpus[fired_target_num], ++ target_state[fired_target_num].data_len, ++ block->data, ++ target_state[fired_target_num].block_id, ++ /* do not ack target data in sync mode, ++ esp32_apptrace_handle_trace_block() can write response data and will do ack thereafter */ ++ ctx->mode != ESP_APPTRACE_CMD_MODE_SYNC); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_TARGET_ERROR(ctx->cpus[fired_target_num], "Failed to read data!"); ++ return res; ++ } ++ ctx->last_blk_id = target_state[fired_target_num].block_id; ++ block->data_len = target_state[fired_target_num].data_len; ++ ctx->raw_tot_len += block->data_len; ++ if (s_time_stats_enable) { ++ if (duration_measure(&blk_proc_time) != 0) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to measure block read time!"); ++ return ERROR_FAIL; ++ } ++ /* update stats */ ++ float brt = duration_elapsed(&blk_proc_time); ++ if (brt > ctx->stats.max_blk_read_time) ++ ctx->stats.max_blk_read_time = brt; ++ if (brt < ctx->stats.min_blk_read_time) ++ ctx->stats.min_blk_read_time = brt; ++ ++ if (duration_start(&blk_proc_time) != 0) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to start block proc time measurement!"); ++ return ERROR_FAIL; ++ } ++ } ++ /* in sync mode do not ack target data on other cores, esp32_apptrace_handle_trace_block() can write response ++ * data and will do ack thereafter */ ++ if (ctx->mode != ESP_APPTRACE_CMD_MODE_SYNC) { ++ for (unsigned int i = 0; i < ctx->cores_num; i++) { ++ if (i == fired_target_num) ++ continue; ++ res = ctx->hw->ctrl_reg_write(ctx->cpus[i], ++ ctx->last_blk_id, ++ 0 /*all read*/, ++ true /*host connected*/, ++ false /*no host data*/); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_TARGET_ERROR(ctx->cpus[i], "Failed to ack data!"); ++ return res; ++ } ++ LOG_TARGET_DEBUG(ctx->cpus[i], "Ack block %" PRId32, ctx->last_blk_id); ++ } ++ res = esp32_apptrace_ready_block_put(ctx, block); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_TARGET_ERROR(ctx->cpus[fired_target_num], "Failed to put ready block of data!"); ++ return res; ++ } ++ } else { ++ res = esp32_apptrace_handle_trace_block(ctx, block); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to process trace block %" PRId32 " bytes!", block->data_len); ++ return res; ++ } ++ res = esp32_apptrace_block_free(ctx, block); ++ if (res != ERROR_OK) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to free ready block!"); ++ return res; ++ } ++ } ++ if (ctx->stop_tmo != -1.0) { ++ /* start idle time measurement */ ++ if (duration_start(&ctx->idle_time) != 0) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to start idle time measure!"); ++ return ERROR_FAIL; ++ } ++ } ++ if (s_time_stats_enable) { ++ if (duration_measure(&blk_proc_time) != 0) { ++ ctx->running = 0; ++ LOG_ERROR("Failed to stop block proc time measure!"); ++ return ERROR_FAIL; ++ } ++ /* update stats */ ++ float bt = duration_elapsed(&blk_proc_time); ++ if (bt > ctx->stats.max_blk_proc_time) ++ ctx->stats.max_blk_proc_time = bt; ++ if (bt < ctx->stats.min_blk_proc_time) ++ ctx->stats.min_blk_proc_time = bt; ++ } ++ return ERROR_OK; ++} ++ ++static void esp32_apptrace_cmd_stop(struct esp32_apptrace_cmd_ctx *ctx) ++{ ++ if (duration_measure(&ctx->read_time) != 0) ++ LOG_ERROR("Failed to stop trace read time measurement!"); ++ int res = target_unregister_timer_callback(esp32_apptrace_poll, ctx); ++ if (res != ERROR_OK) ++ LOG_ERROR("Failed to unregister target timer handler (%d)!", res); ++ ++ /* data processor is alive, so wait for all received blocks to be processed */ ++ res = esp32_apptrace_wait_tracing_finished(ctx); ++ if (res != ERROR_OK) ++ LOG_ERROR("Failed to wait for pended blocks (%d)!", res); ++ res = esp32_apptrace_connect_targets(ctx, false, ctx->target_state == TARGET_RUNNING); ++ if (res != ERROR_OK) ++ LOG_ERROR("Failed to disconnect targets (%d)!", res); ++ esp32_apptrace_print_stats(ctx); ++ res = esp32_apptrace_cmd_cleanup(ctx); ++ if (res != ERROR_OK) ++ LOG_ERROR("Failed to cleanup cmd ctx (%d)!", res); ++} ++ ++int esp32_cmd_apptrace_generic(struct command_invocation *cmd, int mode, const char **argv, int argc) ++{ ++ static struct esp32_apptrace_cmd_ctx s_at_cmd_ctx; ++ struct esp32_apptrace_cmd_data *cmd_data; ++ int res = ERROR_FAIL; ++ enum target_state old_state; ++ struct target *target = get_current_target(CMD_CTX); ++ ++ if (argc < 1) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ ++ /* command can be invoked on unexamined core, if so find examined one */ ++ if (target->smp && !target_was_examined(target)) { ++ struct target_list *head; ++ struct target *curr; ++ LOG_WARNING("Current target '%s' was not examined!", target_name(target)); ++ foreach_smp_target(head, target->smp_targets) { ++ curr = head->target; ++ if (target_was_examined(curr)) { ++ target = curr; ++ LOG_WARNING("Run command on target '%s'", target_name(target)); ++ break; ++ } ++ } ++ } ++ old_state = target->state; ++ ++ if (strcmp(argv[0], "start") == 0) { ++ res = esp32_apptrace_cmd_init(&s_at_cmd_ctx, ++ cmd, ++ mode, ++ &argv[1], ++ argc - 1); ++ if (res != ERROR_OK) { ++ command_print(cmd, "Failed to init cmd ctx (%d)!", res); ++ return res; ++ } ++ cmd_data = s_at_cmd_ctx.cmd_priv; ++ s_at_cmd_ctx.process_data = esp32_apptrace_process_data; ++ s_at_cmd_ctx.auto_clean = esp32_apptrace_cmd_stop; ++ if (cmd_data->wait4halt) { ++ res = esp32_apptrace_wait4halt(&s_at_cmd_ctx, target); ++ if (res != ERROR_OK) { ++ command_print(cmd, "Failed to wait for halt target (%d)!", res); ++ goto _on_start_error; ++ } ++ } ++ res = esp32_apptrace_connect_targets(&s_at_cmd_ctx, true, old_state == TARGET_RUNNING); ++ if (res != ERROR_OK) { ++ command_print(cmd, "Failed to connect to targets (%d)!", res); ++ goto _on_start_error; ++ } ++ res = target_register_timer_callback(esp32_apptrace_poll, ++ cmd_data->poll_period, ++ TARGET_TIMER_TYPE_PERIODIC, ++ &s_at_cmd_ctx); ++ if (res != ERROR_OK) { ++ command_print(cmd, "Failed to register target timer handler (%d)!", res); ++ goto _on_start_error; ++ } ++ } else if (strcmp(argv[0], "stop") == 0) { ++ if (!s_at_cmd_ctx.running) { ++ command_print(cmd, "Tracing is not running!"); ++ return ERROR_FAIL; ++ } ++ esp32_apptrace_cmd_stop(&s_at_cmd_ctx); ++ return ERROR_OK; ++ } else if (strcmp(argv[0], "status") == 0) { ++ if (s_at_cmd_ctx.running && duration_measure(&s_at_cmd_ctx.read_time) != 0) ++ LOG_ERROR("Failed to measure trace read time!"); ++ esp32_apptrace_print_stats(&s_at_cmd_ctx); ++ return ERROR_OK; ++ } else if (strcmp(argv[0], "dump") == 0) { ++ /* [dump outfile] - post-mortem dump without connection to targets */ ++ res = esp32_apptrace_cmd_init(&s_at_cmd_ctx, ++ cmd, ++ mode, ++ &argv[1], ++ argc - 1); ++ if (res != ERROR_OK) { ++ command_print(cmd, "Failed to init cmd ctx (%d)!", res); ++ return res; ++ } ++ s_at_cmd_ctx.stop_tmo = 0.01; /* use small stop tmo */ ++ s_at_cmd_ctx.process_data = esp32_apptrace_process_data; ++ /* check for exit signal and command completion */ ++ while (!openocd_is_shutdown_pending() && s_at_cmd_ctx.running) { ++ res = esp32_apptrace_poll(&s_at_cmd_ctx); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to poll target for trace data (%d)!", res); ++ break; ++ } ++ /* let registered timer callbacks to run */ ++ target_call_timer_callbacks(); ++ } ++ if (s_at_cmd_ctx.running) { ++ /* data processor is alive, so wait for all received blocks to be processed */ ++ res = esp32_apptrace_wait_tracing_finished(&s_at_cmd_ctx); ++ if (res != ERROR_OK) ++ LOG_ERROR("Failed to wait for pended blocks (%d)!", res); ++ } ++ esp32_apptrace_print_stats(&s_at_cmd_ctx); ++ res = esp32_apptrace_cmd_cleanup(&s_at_cmd_ctx); ++ if (res != ERROR_OK) ++ command_print(cmd, "Failed to cleanup cmd ctx (%d)!", res); ++ } else { ++ command_print(cmd, "Invalid action '%s'!", argv[0]); ++ } ++ ++ return res; ++ ++_on_start_error: ++ s_at_cmd_ctx.running = 0; ++ esp32_apptrace_cmd_cleanup(&s_at_cmd_ctx); ++ return res; ++} ++ ++COMMAND_HANDLER(esp32_cmd_apptrace) ++{ ++ return esp32_cmd_apptrace_generic(CMD, ESP_APPTRACE_CMD_MODE_GEN, CMD_ARGV, CMD_ARGC); ++} ++ ++const struct command_registration esp32_apptrace_command_handlers[] = { ++ { ++ .name = "apptrace", ++ .handler = esp32_cmd_apptrace, ++ .mode = COMMAND_EXEC, ++ .help = ++ "App Tracing: application level trace control. Starts, stops or queries tracing process status.", ++ .usage = ++ "[start [poll_period [trace_size [stop_tmo [wait4halt [skip_size]]]]] | [stop] | [status] | [dump ]", ++ }, ++ COMMAND_REGISTRATION_DONE ++}; +diff --git a/src/target/espressif/esp32_apptrace.h b/src/target/espressif/esp32_apptrace.h +new file mode 100644 +index 000000000..387334222 +--- /dev/null ++++ b/src/target/espressif/esp32_apptrace.h +@@ -0,0 +1,126 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++/*************************************************************************** ++ * ESP32 application trace module * ++ * Copyright (C) 2017-2019 Espressif Systems Ltd. * ++ ***************************************************************************/ ++ ++#ifndef OPENOCD_TARGET_ESP32_APPTRACE_H ++#define OPENOCD_TARGET_ESP32_APPTRACE_H ++ ++#include ++#include ++#include ++ ++#define ESP32_APPTRACE_MAX_CORES_NUM 2 ++ ++struct esp32_apptrace_hw { ++ uint32_t max_block_id; ++ uint32_t (*max_block_size_get)(struct target *target); ++ int (*status_reg_read)(struct target *target, uint32_t *stat); ++ int (*ctrl_reg_write)(struct target *target, ++ uint32_t block_id, ++ uint32_t len, ++ bool conn, ++ bool data); ++ int (*ctrl_reg_read)(struct target *target, ++ uint32_t *block_id, ++ uint32_t *len, ++ bool *conn); ++ int (*data_len_read)(struct target *target, ++ uint32_t *block_id, ++ uint32_t *len); ++ int (*data_read)(struct target *target, ++ uint32_t size, ++ uint8_t *buffer, ++ uint32_t block_id, ++ bool ack); ++ uint32_t (*usr_block_max_size_get)(struct target *target); ++ int (*buffs_write)(struct target *target, ++ uint32_t bufs_num, ++ uint32_t buf_sz[], ++ const uint8_t *bufs[], ++ uint32_t block_id, ++ bool ack, ++ bool data); ++ int (*leave_trace_crit_section_start)(struct target *target); ++ int (*leave_trace_crit_section_stop)(struct target *target); ++}; ++ ++struct esp_apptrace_host2target_hdr { ++ uint16_t block_sz; ++}; ++ ++struct esp32_apptrace_dest { ++ void *priv; ++ int (*write)(void *priv, uint8_t *data, int size); ++ int (*clean)(void *priv); ++ bool log_progress; ++}; ++ ++struct esp32_apptrace_format { ++ uint32_t hdr_sz; ++ int (*core_id_get)(struct target *target, uint8_t *hdr_buf); ++ uint32_t (*usr_block_len_get)(struct target *target, uint8_t *hdr_buf, uint32_t *wr_len); ++}; ++ ++struct esp32_apptrace_cmd_stats { ++ uint32_t incompl_blocks; ++ uint32_t lost_bytes; ++ float min_blk_read_time; ++ float max_blk_read_time; ++ float min_blk_proc_time; ++ float max_blk_proc_time; ++}; ++ ++struct esp32_apptrace_cmd_ctx { ++ volatile int running; ++ int mode; ++ /* TODO: use subtargets from target arch info */ ++ struct target *cpus[ESP32_APPTRACE_MAX_CORES_NUM]; ++ /* TODO: use cores num from target */ ++ unsigned int cores_num; ++ const struct esp32_apptrace_hw *hw; ++ enum target_state target_state; ++ uint32_t last_blk_id; ++ struct list_head free_trace_blocks; ++ struct list_head ready_trace_blocks; ++ uint32_t max_trace_block_sz; ++ struct esp32_apptrace_format trace_format; ++ int (*process_data)(struct esp32_apptrace_cmd_ctx *ctx, unsigned int core_id, uint8_t *data, uint32_t data_len); ++ void (*auto_clean)(struct esp32_apptrace_cmd_ctx *ctx); ++ uint32_t tot_len; ++ uint32_t raw_tot_len; ++ float stop_tmo; ++ struct esp32_apptrace_cmd_stats stats; ++ struct duration read_time; ++ struct duration idle_time; ++ void *cmd_priv; ++ struct target *target; ++ struct command_invocation *cmd; ++}; ++ ++struct esp32_apptrace_cmd_data { ++ struct esp32_apptrace_dest data_dest; ++ uint32_t poll_period; ++ uint32_t max_len; ++ uint32_t skip_len; ++ bool wait4halt; ++}; ++ ++int esp32_apptrace_cmd_ctx_init(struct esp32_apptrace_cmd_ctx *cmd_ctx, struct command_invocation *cmd, int mode); ++int esp32_apptrace_cmd_ctx_cleanup(struct esp32_apptrace_cmd_ctx *cmd_ctx); ++void esp32_apptrace_cmd_args_parse(struct esp32_apptrace_cmd_ctx *cmd_ctx, ++ struct esp32_apptrace_cmd_data *cmd_data, ++ const char **argv, ++ int argc); ++int esp32_apptrace_dest_init(struct esp32_apptrace_dest dest[], const char *dest_paths[], unsigned int max_dests); ++int esp32_apptrace_dest_cleanup(struct esp32_apptrace_dest dest[], unsigned int max_dests); ++int esp_apptrace_usr_block_write(const struct esp32_apptrace_hw *hw, struct target *target, ++ uint32_t block_id, ++ const uint8_t *data, ++ uint32_t size); ++ ++extern const struct command_registration esp32_apptrace_command_handlers[]; ++ ++#endif /* OPENOCD_TARGET_ESP32_APPTRACE_H */ +diff --git a/src/target/espressif/esp32s2.c b/src/target/espressif/esp32s2.c +index 64fa69057..a11d05f0f 100644 +--- a/src/target/espressif/esp32s2.c ++++ b/src/target/espressif/esp32s2.c +@@ -496,6 +496,11 @@ static const struct command_registration esp32s2_command_handlers[] = { + { + .chain = xtensa_command_handlers, + }, ++ { ++ .name = "esp", ++ .usage = "", ++ .chain = esp32_apptrace_command_handlers, ++ }, + { + .name = "arm", + .mode = COMMAND_ANY, +diff --git a/src/target/espressif/esp32s3.c b/src/target/espressif/esp32s3.c +index 62b22b135..485567836 100644 +--- a/src/target/espressif/esp32s3.c ++++ b/src/target/espressif/esp32s3.c +@@ -364,6 +364,11 @@ static const struct command_registration esp32s3_command_handlers[] = { + .usage = "", + .chain = esp_xtensa_smp_command_handlers, + }, ++ { ++ .name = "esp", ++ .usage = "", ++ .chain = esp32_apptrace_command_handlers, ++ }, + { + .name = "esp32", + .usage = "", +diff --git a/src/target/espressif/esp_xtensa.c b/src/target/espressif/esp_xtensa.c +index fcc340c82..44764aeca 100644 +--- a/src/target/espressif/esp_xtensa.c ++++ b/src/target/espressif/esp_xtensa.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include "esp_xtensa_apptrace.h" + #include + #include "esp_xtensa.h" + #include "esp_semihosting.h" +@@ -25,6 +26,7 @@ int esp_xtensa_init_arch_info(struct target *target, + if (ret != ERROR_OK) + return ret; + esp_xtensa->semihost.ops = (struct esp_semihost_ops *)semihost_ops; ++ esp_xtensa->apptrace.hw = &esp_xtensa_apptrace_hw; + return ERROR_OK; + } + +diff --git a/src/target/espressif/esp_xtensa.h b/src/target/espressif/esp_xtensa.h +index 1ad6c377f..8807f0c32 100644 +--- a/src/target/espressif/esp_xtensa.h ++++ b/src/target/espressif/esp_xtensa.h +@@ -12,10 +12,12 @@ + #include + #include "esp_xtensa.h" + #include "esp_semihosting.h" ++#include "esp_xtensa_apptrace.h" + + struct esp_xtensa_common { + struct xtensa xtensa; /* must be the first element */ + struct esp_semihost_data semihost; ++ struct esp_xtensa_apptrace_info apptrace; + }; + + static inline struct esp_xtensa_common *target_to_esp_xtensa(struct target *target) +diff --git a/src/target/espressif/esp_xtensa_apptrace.c b/src/target/espressif/esp_xtensa_apptrace.c +new file mode 100644 +index 000000000..dfb846da0 +--- /dev/null ++++ b/src/target/espressif/esp_xtensa_apptrace.c +@@ -0,0 +1,497 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++/*************************************************************************** ++ * Xtensa application tracing module for OpenOCD * ++ * Copyright (C) 2017 Espressif Systems Ltd. * ++ ***************************************************************************/ ++ ++/* ++ How it works? ++ https://github.com/espressif/esp-idf/blob/master/components/app_trace/port/xtensa/port.c#L8 ++*/ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++#include "esp_xtensa_apptrace.h" ++ ++/* TRAX is disabled, so we use its registers for our own purposes ++ * | 31..XXXXXX..24 | 23 .(host_connect). 23 | 22 .(host_data). 22| 21..(block_id)..15 | 14..(block_len)..0 | ++ */ ++#define XTENSA_APPTRACE_CTRL_REG XDMREG_DELAYCNT ++#define XTENSA_APPTRACE_BLOCK_ID_MSK 0x7FUL ++#define XTENSA_APPTRACE_BLOCK_ID_MAX XTENSA_APPTRACE_BLOCK_ID_MSK ++/* if non-zero then apptrace code entered the critical section and the value is an address of the ++ * critical section's exit point */ ++#define XTENSA_APPTRACE_STAT_REG XDMREG_TRIGGERPC ++ ++#define XTENSA_APPTRACE_BLOCK_LEN_MSK 0x7FFFUL ++#define XTENSA_APPTRACE_BLOCK_LEN(_l_) ((_l_) & XTENSA_APPTRACE_BLOCK_LEN_MSK) ++#define XTENSA_APPTRACE_BLOCK_LEN_GET(_v_) ((_v_) & XTENSA_APPTRACE_BLOCK_LEN_MSK) ++#define XTENSA_APPTRACE_BLOCK_ID(_id_) (((_id_) & XTENSA_APPTRACE_BLOCK_ID_MSK) << 15) ++#define XTENSA_APPTRACE_BLOCK_ID_GET(_v_) (((_v_) >> 15) & XTENSA_APPTRACE_BLOCK_ID_MSK) ++#define XTENSA_APPTRACE_HOST_DATA BIT(22) ++#define XTENSA_APPTRACE_HOST_CONNECT BIT(23) ++ ++static int esp_xtensa_apptrace_leave_crit_section_start(struct target *target); ++static int esp_xtensa_apptrace_leave_crit_section_stop(struct target *target); ++static int esp_xtensa_apptrace_buffs_write(struct target *target, ++ uint32_t bufs_num, ++ uint32_t buf_sz[], ++ const uint8_t *bufs[], ++ uint32_t block_id, ++ bool ack, ++ bool data); ++ ++struct esp32_apptrace_hw esp_xtensa_apptrace_hw = { ++ .max_block_id = XTENSA_APPTRACE_BLOCK_ID_MAX, ++ .max_block_size_get = esp_xtensa_apptrace_block_max_size_get, ++ .status_reg_read = esp_xtensa_apptrace_status_reg_read, ++ .ctrl_reg_write = esp_xtensa_apptrace_ctrl_reg_write, ++ .ctrl_reg_read = esp_xtensa_apptrace_ctrl_reg_read, ++ .data_len_read = esp_xtensa_apptrace_data_len_read, ++ .data_read = esp_xtensa_apptrace_data_read, ++ .usr_block_max_size_get = esp_xtensa_apptrace_usr_block_max_size_get, ++ .buffs_write = esp_xtensa_apptrace_buffs_write, ++ .leave_trace_crit_section_start = esp_xtensa_apptrace_leave_crit_section_start, ++ .leave_trace_crit_section_stop = esp_xtensa_apptrace_leave_crit_section_stop, ++}; ++ ++uint32_t esp_xtensa_apptrace_block_max_size_get(struct target *target) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ struct xtensa_trace_status trace_status; ++ struct xtensa_trace_config trace_config; ++ uint32_t max_trace_block_sz; ++ ++ int res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to read TRAX status (%d)!", res); ++ return 0; ++ } ++ ++ max_trace_block_sz = BIT(((trace_status.stat >> 8) & 0x1f) - 2) * 4; ++ res = xtensa_dm_trace_config_read(&xtensa->dbg_mod, &trace_config); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to read TRAX config (%d)!", res); ++ return 0; ++ } ++ LOG_DEBUG("ctrl=0x%" PRIx32 " memadrstart=0x%" PRIx32 " memadrend=0x%" PRIx32 " traxadr=0x%" PRIx32, ++ trace_config.ctrl, ++ trace_config.memaddr_start, ++ trace_config.memaddr_end, ++ trace_config.addr); ++ ++ return max_trace_block_sz; ++} ++ ++uint32_t esp_xtensa_apptrace_usr_block_max_size_get(struct target *target) ++{ ++ return esp_xtensa_apptrace_block_max_size_get(target) - sizeof(struct esp_apptrace_host2target_hdr); ++} ++ ++int esp_xtensa_apptrace_data_len_read(struct target *target, ++ uint32_t *block_id, ++ uint32_t *len) ++{ ++ return esp_xtensa_apptrace_ctrl_reg_read(target, block_id, len, NULL); ++} ++ ++int esp_xtensa_apptrace_usr_block_write(struct target *target, ++ uint32_t block_id, ++ const uint8_t *data, ++ uint32_t size) ++{ ++ return esp_apptrace_usr_block_write(&esp_xtensa_apptrace_hw, target, block_id, data, size); ++} ++ ++static int esp_xtensa_apptrace_data_reverse_read(struct xtensa *xtensa, ++ uint32_t size, ++ uint8_t *buffer, ++ uint8_t *unal_bytes) ++{ ++ int res = 0; ++ uint32_t rd_sz = ALIGN_UP(size, 4); ++ ++ res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXADDR, (xtensa->core_config->trace.mem_sz - rd_sz) / 4); ++ if (res != ERROR_OK) ++ return res; ++ if (!IS_ALIGNED(size, 4)) { ++ res = xtensa_queue_dbg_reg_read(xtensa, XDMREG_TRAXDATA, unal_bytes); ++ if (res != ERROR_OK) ++ return res; ++ } ++ for (unsigned int i = size / 4; i != 0; i--) { ++ res = xtensa_queue_dbg_reg_read(xtensa, XDMREG_TRAXDATA, &buffer[(i - 1) * 4]); ++ if (res != ERROR_OK) ++ return res; ++ } ++ return ERROR_OK; ++} ++ ++static int esp_xtensa_apptrace_data_normal_read(struct xtensa *xtensa, ++ uint32_t size, ++ uint8_t *buffer, ++ uint8_t *unal_bytes) ++{ ++ int res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXADDR, 0); ++ if (res != ERROR_OK) ++ return res; ++ for (unsigned int i = 0; i < size / 4; i++) { ++ res = xtensa_queue_dbg_reg_read(xtensa, XDMREG_TRAXDATA, &buffer[i * 4]); ++ if (res != ERROR_OK) ++ return res; ++ } ++ if (!IS_ALIGNED(size, 4)) { ++ res = xtensa_queue_dbg_reg_read(xtensa, XDMREG_TRAXDATA, unal_bytes); ++ if (res != ERROR_OK) ++ return res; ++ } ++ return ERROR_OK; ++} ++ ++int esp_xtensa_apptrace_data_read(struct target *target, ++ uint32_t size, ++ uint8_t *buffer, ++ uint32_t block_id, ++ bool ack) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ int res; ++ uint32_t tmp = XTENSA_APPTRACE_HOST_CONNECT | XTENSA_APPTRACE_BLOCK_ID(block_id) | ++ XTENSA_APPTRACE_BLOCK_LEN(0); ++ uint8_t unal_bytes[4]; ++ ++ LOG_DEBUG("Read data on target (%s)", target_name(target)); ++ if (xtensa->core_config->trace.reversed_mem_access) ++ res = esp_xtensa_apptrace_data_reverse_read(xtensa, size, buffer, unal_bytes); ++ else ++ res = esp_xtensa_apptrace_data_normal_read(xtensa, size, buffer, unal_bytes); ++ if (res != ERROR_OK) ++ return res; ++ if (ack) { ++ LOG_DEBUG("Ack block %" PRIu32 " target (%s)!", block_id, target_name(target)); ++ res = xtensa_queue_dbg_reg_write(xtensa, XTENSA_APPTRACE_CTRL_REG, tmp); ++ if (res != ERROR_OK) ++ return res; ++ } ++ xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); ++ res = xtensa_dm_queue_execute(&xtensa->dbg_mod); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to exec JTAG queue!"); ++ return res; ++ } ++ if (!IS_ALIGNED(size, 4)) { ++ /* copy the last unaligned bytes */ ++ memcpy(buffer + ALIGN_DOWN(size, 4), unal_bytes, size & 0x3UL); ++ } ++ return ERROR_OK; ++} ++ ++int esp_xtensa_apptrace_ctrl_reg_write(struct target *target, ++ uint32_t block_id, ++ uint32_t len, ++ bool conn, ++ bool data) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ uint32_t tmp = (conn ? XTENSA_APPTRACE_HOST_CONNECT : 0) | ++ (data ? XTENSA_APPTRACE_HOST_DATA : 0) | XTENSA_APPTRACE_BLOCK_ID(block_id) | ++ XTENSA_APPTRACE_BLOCK_LEN(len); ++ ++ xtensa_queue_dbg_reg_write(xtensa, XTENSA_APPTRACE_CTRL_REG, tmp); ++ xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); ++ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to exec JTAG queue!"); ++ return res; ++ } ++ ++ return ERROR_OK; ++} ++ ++int esp_xtensa_apptrace_ctrl_reg_read(struct target *target, ++ uint32_t *block_id, ++ uint32_t *len, ++ bool *conn) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ uint8_t tmp[4]; ++ ++ xtensa_queue_dbg_reg_read(xtensa, XTENSA_APPTRACE_CTRL_REG, tmp); ++ xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); ++ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); ++ if (res != ERROR_OK) ++ return res; ++ uint32_t val = target_buffer_get_u32(target, tmp); ++ if (block_id) ++ *block_id = XTENSA_APPTRACE_BLOCK_ID_GET(val); ++ if (len) ++ *len = XTENSA_APPTRACE_BLOCK_LEN_GET(val); ++ if (conn) ++ *conn = val & XTENSA_APPTRACE_HOST_CONNECT; ++ return ERROR_OK; ++} ++ ++int esp_xtensa_apptrace_status_reg_read(struct target *target, uint32_t *stat) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ uint8_t tmp[4]; ++ ++ xtensa_queue_dbg_reg_read(xtensa, XTENSA_APPTRACE_STAT_REG, tmp); ++ xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); ++ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to exec JTAG queue!"); ++ return res; ++ } ++ *stat = buf_get_u32(tmp, 0, 32); ++ return ERROR_OK; ++} ++ ++int esp_xtensa_apptrace_status_reg_write(struct target *target, uint32_t stat) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ ++ xtensa_queue_dbg_reg_write(xtensa, XTENSA_APPTRACE_STAT_REG, stat); ++ xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); ++ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to exec JTAG queue!"); ++ return res; ++ } ++ return ERROR_OK; ++} ++ ++static int esp_xtensa_swdbg_activate(struct target *target, int enab) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ ++ xtensa_queue_dbg_reg_write(xtensa, enab ? XDMREG_DCRSET : XDMREG_DCRCLR, OCDDCR_DEBUGSWACTIVE); ++ xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); ++ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod); ++ if (res != ERROR_OK) { ++ LOG_ERROR("%s: writing DCR failed!", target->cmd_name); ++ return res; ++ } ++ ++ return ERROR_OK; ++} ++ ++static int esp_xtensa_apptrace_leave_crit_section_start(struct target *target) ++{ ++ /* TODO: not sure that we need this, but it seems that we fail to leave tracing critical ++ *section w/o this */ ++ int res = esp_xtensa_swdbg_activate(target, 1 /*enable*/); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to activate SW debug (%d)!", res); ++ return res; ++ } ++ return ERROR_OK; ++} ++ ++static int esp_xtensa_apptrace_leave_crit_section_stop(struct target *target) ++{ ++ int res = esp_xtensa_swdbg_activate(target, 0 /*disable*/); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to activate SW debug (%d)!", res); ++ return res; ++ } ++ return ERROR_OK; ++} ++ ++static int esp_xtensa_apptrace_queue_reverse_write(struct target *target, uint32_t bufs_num, ++ uint32_t buf_sz[], const uint8_t *bufs[]) ++{ ++ int res = ERROR_OK; ++ uint32_t cached_bytes = 0, total_sz = 0; ++ uint8_t cached_data8[sizeof(uint32_t)] = { 0 }; ++ uint32_t cached_data32 = 0; ++ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ ++ for (uint32_t i = 0; i < bufs_num; i++) ++ total_sz += buf_sz[i]; ++ if (!IS_ALIGNED(total_sz, 4)) { ++ cached_bytes = sizeof(uint32_t) - (total_sz & 0x3UL); ++ total_sz = ALIGN_UP(total_sz, 4); ++ } ++ xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXADDR, (xtensa->core_config->trace.mem_sz - total_sz) / 4); ++ for (uint32_t i = bufs_num; i > 0; i--) { ++ uint32_t bsz = buf_sz[i - 1]; ++ const uint8_t *cur_buf = &bufs[i - 1][bsz]; ++ uint32_t bytes_to_cache; ++ /* if there are cached bytes from the previous buffer, combine them with the last ++ * from the current buffer */ ++ if (cached_bytes) { ++ if ((cached_bytes + bsz) < sizeof(uint32_t)) ++ bytes_to_cache = bsz; ++ else ++ bytes_to_cache = sizeof(uint32_t) - cached_bytes; ++ memcpy(&cached_data8[sizeof(uint32_t) - cached_bytes - bytes_to_cache], ++ cur_buf - bytes_to_cache, ++ bytes_to_cache); ++ cached_data32 = target_buffer_get_u32(target, cached_data8); ++ cached_bytes += bytes_to_cache; ++ if (cached_bytes < sizeof(uint32_t)) ++ continue; ++ res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32); ++ if (res != ERROR_OK) ++ return res; ++ bsz -= bytes_to_cache; ++ cur_buf -= bytes_to_cache; ++ memset(cached_data8, 0x00, sizeof(cached_data8)); ++ cached_bytes = 0; ++ } ++ /* write full dwords */ ++ for (unsigned int k = bsz; k >= sizeof(uint32_t); k -= sizeof(uint32_t)) { ++ uint32_t temp = target_buffer_get_u32(target, cur_buf - sizeof(uint32_t)); ++ res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, temp); ++ if (res != ERROR_OK) ++ return res; ++ cur_buf -= sizeof(uint32_t); ++ } ++ /* if there are bytes to be cached (1..3) */ ++ bytes_to_cache = bsz & 0x3UL; ++ if (bytes_to_cache > 0) { ++ if (bytes_to_cache + cached_bytes >= sizeof(uint32_t)) { ++ /* filling the cache buffer from the end to beginning */ ++ uint32_t to_copy = sizeof(uint32_t) - cached_bytes; ++ memcpy(&cached_data8[0], cur_buf - to_copy, to_copy); ++ cached_data32 = target_buffer_get_u32(target, cached_data8); ++ /* write full word of cached bytes */ ++ res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32); ++ if (res != ERROR_OK) ++ return res; ++ /* cache remaining bytes */ ++ memset(cached_data8, 0x00, sizeof(cached_data8)); ++ cur_buf -= to_copy; ++ to_copy = bytes_to_cache + cached_bytes - sizeof(uint32_t); ++ memcpy(&cached_data8[sizeof(uint32_t) - to_copy], cur_buf - to_copy, to_copy); ++ cached_bytes = to_copy; ++ } else { ++ /* filling the cache buffer from the end to beginning */ ++ memcpy(&cached_data8[sizeof(uint32_t) - cached_bytes - bytes_to_cache], ++ cur_buf - bytes_to_cache, ++ bytes_to_cache); ++ cached_bytes += bytes_to_cache; ++ } ++ } ++ } ++ return ERROR_OK; ++} ++ ++static int esp_xtensa_apptrace_queue_normal_write(struct target *target, uint32_t bufs_num, ++ uint32_t buf_sz[], const uint8_t *bufs[]) ++{ ++ int res = ERROR_OK; ++ uint32_t cached_bytes = 0; ++ uint8_t cached_data8[4] = { 0 }; ++ uint32_t cached_data32 = 0; ++ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ ++ /* | 1 | 2 | 1 | 2 | 4 |.......| ++ * | 4 | 4 | 4 | */ ++ xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXADDR, 0); ++ for (unsigned int i = 0; i < bufs_num; i++) { ++ uint32_t bsz = buf_sz[i]; ++ const uint8_t *cur_buf = bufs[i]; ++ uint32_t bytes_to_cache; ++ /* if there are cached bytes from the previous buffer, combine them with the last ++ * from the current buffer */ ++ if (cached_bytes) { ++ if ((cached_bytes + bsz) < sizeof(uint32_t)) ++ bytes_to_cache = bsz; ++ else ++ bytes_to_cache = sizeof(uint32_t) - cached_bytes; ++ memcpy(&cached_data8[cached_bytes], cur_buf, bytes_to_cache); ++ cached_bytes += bytes_to_cache; ++ if (cached_bytes < sizeof(uint32_t)) ++ continue; ++ cached_data32 = target_buffer_get_u32(target, cached_data8); ++ res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32); ++ if (res != ERROR_OK) ++ return res; ++ bsz -= bytes_to_cache; ++ cur_buf += bytes_to_cache; ++ memset(cached_data8, 0x00, sizeof(cached_data8)); ++ cached_bytes = 0; ++ } ++ /* write full dwords */ ++ for (unsigned int k = 0; (k + sizeof(uint32_t)) <= bsz; k += sizeof(uint32_t)) { ++ uint32_t temp = target_buffer_get_u32(target, cur_buf); ++ res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, temp); ++ if (res != ERROR_OK) ++ return res; ++ cur_buf += sizeof(uint32_t); ++ } ++ /* if there are bytes to be cached (1..3) */ ++ bytes_to_cache = bsz & 0x3UL; ++ if (bytes_to_cache > 0) { ++ if (bytes_to_cache + cached_bytes >= sizeof(uint32_t)) { ++ memcpy(&cached_data8[0], cur_buf, sizeof(uint32_t) - cached_bytes); ++ cached_data32 = target_buffer_get_u32(target, cached_data8); ++ /* write full word of cached bytes */ ++ res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32); ++ if (res != ERROR_OK) ++ return res; ++ /* cache remaining bytes */ ++ memset(cached_data8, 0x00, sizeof(cached_data8)); ++ cur_buf += sizeof(uint32_t) - cached_bytes; ++ cached_bytes = bytes_to_cache + cached_bytes - sizeof(uint32_t); ++ memcpy(&cached_data8[0], cur_buf, cached_bytes); ++ } else { ++ memcpy(&cached_data8[cached_bytes], cur_buf, bytes_to_cache); ++ cached_bytes += bytes_to_cache; ++ } ++ } ++ } ++ if (cached_bytes) { ++ /* write remaining cached bytes */ ++ cached_data32 = target_buffer_get_u32(target, cached_data8); ++ res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32); ++ if (res != ERROR_OK) ++ return res; ++ } ++ return ERROR_OK; ++} ++ ++static int esp_xtensa_apptrace_buffs_write(struct target *target, ++ uint32_t bufs_num, ++ uint32_t buf_sz[], ++ const uint8_t *bufs[], ++ uint32_t block_id, ++ bool ack, ++ bool data) ++{ ++ struct xtensa *xtensa = target_to_xtensa(target); ++ int res = ERROR_OK; ++ uint32_t tmp = XTENSA_APPTRACE_HOST_CONNECT | ++ (data ? XTENSA_APPTRACE_HOST_DATA : 0) | XTENSA_APPTRACE_BLOCK_ID(block_id) | ++ XTENSA_APPTRACE_BLOCK_LEN(0); ++ ++ if (xtensa->core_config->trace.reversed_mem_access) ++ res = esp_xtensa_apptrace_queue_reverse_write(target, bufs_num, buf_sz, bufs); ++ else ++ res = esp_xtensa_apptrace_queue_normal_write(target, bufs_num, buf_sz, bufs); ++ if (res != ERROR_OK) ++ return res; ++ if (ack) { ++ LOG_DEBUG("Ack block %" PRId32 " on target (%s)!", block_id, target_name(target)); ++ res = xtensa_queue_dbg_reg_write(xtensa, XTENSA_APPTRACE_CTRL_REG, tmp); ++ if (res != ERROR_OK) ++ return res; ++ } ++ xtensa_dm_queue_tdi_idle(&xtensa->dbg_mod); ++ res = xtensa_dm_queue_execute(&xtensa->dbg_mod); ++ if (res != ERROR_OK) { ++ LOG_ERROR("Failed to exec JTAG queue!"); ++ return res; ++ } ++ return ERROR_OK; ++} +diff --git a/src/target/espressif/esp_xtensa_apptrace.h b/src/target/espressif/esp_xtensa_apptrace.h +new file mode 100644 +index 000000000..0a9be731f +--- /dev/null ++++ b/src/target/espressif/esp_xtensa_apptrace.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++ ++/*************************************************************************** ++ * Xtensa application tracing module for OpenOCD * ++ * Copyright (C) 2017 Espressif Systems Ltd. * ++ ***************************************************************************/ ++ ++#ifndef OPENOCD_TARGET_ESP_XTENSA_APPTRACE_H ++#define OPENOCD_TARGET_ESP_XTENSA_APPTRACE_H ++ ++#include "esp32_apptrace.h" ++ ++struct esp_xtensa_apptrace_info { ++ const struct esp32_apptrace_hw *hw; ++}; ++ ++extern struct esp32_apptrace_hw esp_xtensa_apptrace_hw; ++ ++int esp_xtensa_apptrace_data_len_read(struct target *target, uint32_t *block_id, uint32_t *len); ++int esp_xtensa_apptrace_data_read(struct target *target, ++ uint32_t size, ++ uint8_t *buffer, ++ uint32_t block_id, ++ bool ack); ++int esp_xtensa_apptrace_ctrl_reg_read(struct target *target, uint32_t *block_id, uint32_t *len, bool *conn); ++int esp_xtensa_apptrace_ctrl_reg_write(struct target *target, ++ uint32_t block_id, ++ uint32_t len, ++ bool conn, ++ bool data); ++int esp_xtensa_apptrace_status_reg_write(struct target *target, uint32_t stat); ++int esp_xtensa_apptrace_status_reg_read(struct target *target, uint32_t *stat); ++uint32_t esp_xtensa_apptrace_block_max_size_get(struct target *target); ++uint32_t esp_xtensa_apptrace_usr_block_max_size_get(struct target *target); ++int esp_xtensa_apptrace_usr_block_write(struct target *target, uint32_t block_id, const uint8_t *data, uint32_t size); ++ ++#endif /* OPENOCD_TARGET_ESP_XTENSA_APPTRACE_H */ diff --git a/meta-oe/recipes-devtools/openocd/openocd/0147-src-server-Fix-memory-leak-of-reg_list.patch b/meta-oe/recipes-devtools/openocd/openocd/0147-src-server-Fix-memory-leak-of-reg_list.patch new file mode 100644 index 000000000..fb5757d4f --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0147-src-server-Fix-memory-leak-of-reg_list.patch @@ -0,0 +1,28 @@ +From 1c31f6225f41dd2bd371571e829fbf6855788d24 Mon Sep 17 00:00:00 2001 +From: panciyan +Date: Fri, 31 Mar 2023 15:12:08 +0000 +Subject: [PATCH] src/server: Fix memory leak of reg_list + +memory leak of reg_list when local_list realloc fail. + +Signed-off-by: panciyan +Change-Id: I6b09137ecd132ab326205f5a575a38bcc82e8469 +Reviewed-on: https://review.openocd.org/c/openocd/+/7566 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/server/gdb_server.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c +index d8dbc2c8b..b15a6c1c3 100644 +--- a/src/server/gdb_server.c ++++ b/src/server/gdb_server.c +@@ -2348,6 +2348,7 @@ static int smp_reg_list_noread(struct target *target, + local_list = realloc(local_list, combined_allocated * sizeof(struct reg *)); + if (!local_list) { + LOG_ERROR("realloc(%zu) failed", combined_allocated * sizeof(struct reg *)); ++ free(reg_list); + return ERROR_FAIL; + } + } diff --git a/meta-oe/recipes-devtools/openocd/openocd/0148-rtos-linux.c-Fix-Linux-user-space-border-check.patch b/meta-oe/recipes-devtools/openocd/openocd/0148-rtos-linux.c-Fix-Linux-user-space-border-check.patch new file mode 100644 index 000000000..8a5875c77 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0148-rtos-linux.c-Fix-Linux-user-space-border-check.patch @@ -0,0 +1,29 @@ +From 1e6df1675ccea95d99d767e6d2b9a735c8ee2a36 Mon Sep 17 00:00:00 2001 +From: panciyan +Date: Sun, 2 Apr 2023 05:17:17 +0000 +Subject: [PATCH] rtos/linux.c: Fix Linux user space border check + +Linux kernel and user space border is 0xc0000000 not 0xc000000 + +Signed-off-by: panciyan +Change-Id: I6b487cce62ac31737deca97d5f5f7bbc081280f4 +Reviewed-on: https://review.openocd.org/c/openocd/+/7570 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/rtos/linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/rtos/linux.c b/src/rtos/linux.c +index f9edabc2b..7517ec7a9 100644 +--- a/src/rtos/linux.c ++++ b/src/rtos/linux.c +@@ -123,7 +123,7 @@ static int linux_read_memory(struct target *target, + target->rtos->rtos_specific_params; + uint32_t pa = (address & linux_os->phys_mask) + linux_os->phys_base; + #endif +- if (address < 0xc000000) { ++ if (address < 0xc0000000) { + LOG_ERROR("linux awareness : address in user space"); + return ERROR_FAIL; + } diff --git a/meta-oe/recipes-devtools/openocd/openocd/0149-flash-rsl10-fix-typo.patch b/meta-oe/recipes-devtools/openocd/openocd/0149-flash-rsl10-fix-typo.patch new file mode 100644 index 000000000..d2f74a5ec --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0149-flash-rsl10-fix-typo.patch @@ -0,0 +1,27 @@ +From 95c27731d4f76c0554147030075ab476d68f9f83 Mon Sep 17 00:00:00 2001 +From: Mark Zhuang +Date: Mon, 10 Apr 2023 10:57:55 +0800 +Subject: [PATCH] flash/rsl10: fix typo + +Change-Id: I11af37309fe4684fcb340a00fcc7b2096b8dad76 +Signed-off-by: Mark Zhuang +Reviewed-on: https://review.openocd.org/c/openocd/+/7584 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + contrib/loaders/flash/rsl10/rom_launcher.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/contrib/loaders/flash/rsl10/rom_launcher.S b/contrib/loaders/flash/rsl10/rom_launcher.S +index 70f000e72..aafedfb46 100644 +--- a/contrib/loaders/flash/rsl10/rom_launcher.S ++++ b/contrib/loaders/flash/rsl10/rom_launcher.S +@@ -21,7 +21,7 @@ + .global _start + _start: + launch_program_in_rom: +- // variables are already set, addres to jump is in r3 ++ // variables are already set, address to jump is in r3 + blx r3 + exit: + // Wait for OpenOCD diff --git a/meta-oe/recipes-devtools/openocd/openocd/0150-pld-move-file-sanity-checks-to-pld.c.patch b/meta-oe/recipes-devtools/openocd/openocd/0150-pld-move-file-sanity-checks-to-pld.c.patch new file mode 100644 index 000000000..2b98c2732 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0150-pld-move-file-sanity-checks-to-pld.c.patch @@ -0,0 +1,90 @@ +From 91bd4313444c5a949ce49d88ab487608df7d6c37 Mon Sep 17 00:00:00 2001 +From: Daniel Anselmi +Date: Wed, 14 Dec 2022 09:27:38 +0100 +Subject: [PATCH] pld: move file sanity checks to pld.c + +Change-Id: Id64b1165b25a03634949ac22b8af16eb0e24c1fa +Signed-off-by: Daniel Anselmi +Reviewed-on: https://review.openocd.org/c/openocd/+/7388 +Tested-by: jenkins +Reviewed-by: Antonio Borneo +--- + src/pld/pld.c | 17 +++++++++++++++++ + src/pld/xilinx_bit.c | 17 ----------------- + 2 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/src/pld/pld.c b/src/pld/pld.c +index e2e0ef413..af1836907 100644 +--- a/src/pld/pld.c ++++ b/src/pld/pld.c +@@ -10,6 +10,7 @@ + #endif + + #include "pld.h" ++#include + #include + #include + #include +@@ -134,6 +135,22 @@ COMMAND_HANDLER(handle_pld_load_command) + return ERROR_OK; + } + ++ struct stat input_stat; ++ if (stat(CMD_ARGV[1], &input_stat) == -1) { ++ LOG_ERROR("couldn't stat() %s: %s", CMD_ARGV[1], strerror(errno)); ++ return ERROR_PLD_FILE_LOAD_FAILED; ++ } ++ ++ if (S_ISDIR(input_stat.st_mode)) { ++ LOG_ERROR("%s is a directory", CMD_ARGV[1]); ++ return ERROR_PLD_FILE_LOAD_FAILED; ++ } ++ ++ if (input_stat.st_size == 0) { ++ LOG_ERROR("Empty file %s", CMD_ARGV[1]); ++ return ERROR_PLD_FILE_LOAD_FAILED; ++ } ++ + retval = p->driver->load(p, CMD_ARGV[1]); + if (retval != ERROR_OK) { + command_print(CMD, "failed loading file %s to pld device %u", +diff --git a/src/pld/xilinx_bit.c b/src/pld/xilinx_bit.c +index 792b3375b..e4cc52ef9 100644 +--- a/src/pld/xilinx_bit.c ++++ b/src/pld/xilinx_bit.c +@@ -13,7 +13,6 @@ + #include "pld.h" + #include + +-#include + #include + + static int read_section(FILE *input_file, int length_size, char section, +@@ -60,27 +59,11 @@ static int read_section(FILE *input_file, int length_size, char section, + int xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename) + { + FILE *input_file; +- struct stat input_stat; + int read_count; + + if (!filename || !bit_file) + return ERROR_COMMAND_SYNTAX_ERROR; + +- if (stat(filename, &input_stat) == -1) { +- LOG_ERROR("couldn't stat() %s: %s", filename, strerror(errno)); +- return ERROR_PLD_FILE_LOAD_FAILED; +- } +- +- if (S_ISDIR(input_stat.st_mode)) { +- LOG_ERROR("%s is a directory", filename); +- return ERROR_PLD_FILE_LOAD_FAILED; +- } +- +- if (input_stat.st_size == 0) { +- LOG_ERROR("Empty file %s", filename); +- return ERROR_PLD_FILE_LOAD_FAILED; +- } +- + input_file = fopen(filename, "rb"); + if (!input_file) { + LOG_ERROR("couldn't open %s: %s", filename, strerror(errno)); diff --git a/meta-oe/recipes-devtools/openocd/openocd/0151-Committing-changes-from-do_patch.patch b/meta-oe/recipes-devtools/openocd/openocd/0151-Committing-changes-from-do_patch.patch new file mode 100644 index 000000000..074e9b788 --- /dev/null +++ b/meta-oe/recipes-devtools/openocd/openocd/0151-Committing-changes-from-do_patch.patch @@ -0,0 +1,24 @@ +From 16801a7c4cfd5abe8f7a55e9ddd5c9251c422de0 Mon Sep 17 00:00:00 2001 +From: OpenEmbedded +Date: Fri, 3 Nov 2023 17:29:27 +0000 +Subject: [PATCH] Committing changes from do_patch + +--- + jimtcl | 2 +- + src/jtag/drivers/libjaylink | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/jimtcl b/jimtcl +index 1933e5457..fcbb4499a 160000 +--- a/jimtcl ++++ b/jimtcl +@@ -1 +1 @@ +-Subproject commit 1933e5457b9512d39ebbe11ed32578aada149f49 ++Subproject commit fcbb4499a6b46ef69e7a95da53e30796e20817f0 +diff --git a/src/jtag/drivers/libjaylink b/src/jtag/drivers/libjaylink +index 0d23921a0..9aa7a5957 160000 +--- a/src/jtag/drivers/libjaylink ++++ b/src/jtag/drivers/libjaylink +@@ -1 +1 @@ +-Subproject commit 0d23921a05d5d427332a142d154c213d0c306eb1 ++Subproject commit 9aa7a5957c07bb6e862fc1a6d3153d109c7407e4 diff --git a/meta-oe/recipes-devtools/openocd/openocd_git.bb b/meta-oe/recipes-devtools/openocd/openocd_git.bb index d30d9c346..98c8e5da6 100644 --- a/meta-oe/recipes-devtools/openocd/openocd_git.bb +++ b/meta-oe/recipes-devtools/openocd/openocd_git.bb @@ -4,12 +4,163 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=599d2d1ee7fc84c0467b3d19801db870" DEPENDS = "libusb-compat libftdi" RDEPENDS:${PN} = "libusb1" -SRC_URI = " \ - git://repo.or.cz/openocd.git;protocol=http;name=openocd;branch=master \ - git://repo.or.cz/r/git2cl.git;protocol=http;destsuffix=tools/git2cl;name=git2cl;branch=master \ - git://github.com/msteveb/jimtcl.git;protocol=http;destsuffix=git/jimtcl;name=jimtcl;branch=master \ - git://repo.or.cz/r/libjaylink.git;protocol=http;destsuffix=git/src/jtag/drivers/libjaylink;name=libjaylink;branch=master \ -" +SRCREV = "9ea7f3d647c8ecf6b0f1424002dfc3f4504a162c" +SRC_URI = "git://repo.or.cz/openocd.git;protocol=http;name=openocd;branch=master \ + git://repo.or.cz/r/git2cl.git;protocol=http;destsuffix=tools/git2cl;name=git2cl;branch=master \ + git://github.com/msteveb/jimtcl.git;protocol=http;destsuffix=git/jimtcl;name=jimtcl;branch=master \ + git://repo.or.cz/r/libjaylink.git;protocol=http;destsuffix=git/src/jtag/drivers/libjaylink;name=libjaylink;branch=master \ + file://0001-Restore-normal-development-cycle.patch \ + file://0002-Deprecate-libjaylink-Git-submodule.patch \ + file://0003-nds32-drop-it-together-with-aice-adapter-driver.patch \ + file://0004-openocd-revert-workarounds-for-expr-syntax-change.patch \ + file://0005-flash-nor-avrf-add-ATmega32U4-support.patch \ + file://0006-target-xtensa-remove-needless-target_was_examined-ch.patch \ + file://0007-flash-nor-spi-Add-issi-is25lq040b-to-device-list.patch \ + file://0008-src-rtos-eCos-Support-per-build-configuration-specif.patch \ + file://0009-armv8-Add-support-of-pointer-authentication.patch \ + file://0010-target-armv7m-check-error-in-armv7m_restore_context.patch \ + file://0011-target-cortex_m-add-SMP-support-for-Cortex-M.patch \ + file://0012-flash-nor-rp2040-make-SPI-flash-ID-detection-optiona.patch \ + file://0013-tcl-target-add-SMP-mode-to-rp2040.cfg.patch \ + file://0014-tcl-target-remove-rp2040-core0.cfg.patch \ + file://0015-riscv-drop-deprecated-command-riscv-set_prefer_sba.patch \ + file://0016-riscv-drop-deprecated-command-riscv-test_sba_config_.patch \ + file://0017-adapter-Improve-three-adapter-related-prints.patch \ + file://0018-flash-stm32l4x-avoid-multiple-assignments.patch \ + file://0019-target-armv7m-Rename-xPSR-to-xpsr.patch \ + file://0020-flash-nor-numicro-reorder-the-parts-list.patch \ + file://0021-flash-support-Nuvoton-M541-NUC442-472-series.patch \ + file://0022-tcl-add-a-configuration-file-for-Nuvoton-M541-NUC442.patch \ + file://0023-flash-nor-contrib-loaders-move-numicro-M4-write-asse.patch \ + file://0024-flash-nor-contrib-loaders-move-numicro-M0-write-asse.patch \ + file://0025-doc-usb_adapters-add-container-for-lsusb-dump-of-ada.patch \ + file://0026-doc-usb_adapters-add-lsusb-dump-of-few-adapters.patch \ + file://0027-doc-usb_adapters-add-other-adapters.patch \ + file://0028-tools-add-disassembler-helper-for-files-.inc.patch \ + file://0029-jtag-drivers-cmsis_dap-move-pending-request-FIFO.patch \ + file://0030-jtag-drivers-cmsis_dap-use-dap-parameter-instead-of-.patch \ + file://0031-jtag-drivers-cmsis_dap-use-unsigned-types.patch \ + file://0032-jtag-drivers-cmsis_dap-introduce-packet_usable_size.patch \ + file://0033-jtag-drivers-cmsis_dap-improve-USB-packets-filling.patch \ + file://0034-jtag-drivers-cmsis_dap-speed-up-long-transfers-using.patch \ + file://0035-jtag-drivers-cmsis_dap-prevent-conn-discon-workaroun.patch \ + file://0036-tcl-target-enable-rtos-hwthread.patch \ + file://0037-flash-nor-stm32l4x-Add-revision-X-and-C-for-STM32U57.patch \ + file://0038-.gitignore-Add-.cache-and-compile_commands.json.patch \ + file://0039-jtag-parse-command-options-in-swd-newdap.patch \ + file://0040-jtag-hla-use-generic-helper-for-commands-jtag-newtap.patch \ + file://0041-flash-nor-psoc4-drop-jtag_poll_mask-from-flash-write.patch \ + file://0042-helper-Add-generic-little-endian-CRC32-function.patch \ + file://0043-stm32f3x-Allow-overriding-the-flash-bank-size.patch \ + file://0044-doc-fix-broken-link-to-IgnoreHardwareSerialNumber-in.patch \ + file://0045-doc-usb_adapters-add-lsusb-dump-of-esp_usb_jtag.patch \ + file://0046-rtos-nuttx-move-stacking-info-to-the-new-nuttx-stack.patch \ + file://0047-rtos-nuttx-add-riscv-stacking-info.patch \ + file://0048-rtos-add-custom-stack-read-function.patch \ + file://0049-rtos-nuttx-add-stacking-info-for-Espressif-Xtensa-ch.patch \ + file://0050-rtos-Support-rt-kernel.patch \ + file://0051-rtos-Fix-constness-of-struct-rtos_type.patch \ + file://0052-jtag-drivers-openjtag-fix-annoying-num_cycles-16-war.patch \ + file://0053-jtag-drivers-bitbang-avoid-mostly-harmless-glitch-on.patch \ + file://0054-jtag-drivers-bcm2835gpio-use-rounding-in-delay-math.patch \ + file://0055-jtag-drivers-bcm2835gpio-refactor-delays-to-inline-f.patch \ + file://0056-tcl-interface-universal-config-for-all-Raspberry-Pi-.patch \ + file://0057-rtos-remove-config.h-includes-from-stackings-headers.patch \ + file://0058-jtag-drivers-jlink-allow-SWD-multidrop.patch \ + file://0059-tcl-target-add-rescue-mode-to-RP2040-config.patch \ + file://0060-flash-nor-spi-Add-some-zbit-flash-chips.patch \ + file://0061-target-arc-rewrite-command-arc-jtag-get-aux-reg-as-C.patch \ + file://0062-target-arc-rewrite-command-arc-jtag-set-aux-reg-as-C.patch \ + file://0063-target-arc-rewrite-command-arc-jtag-get-core-reg-as-.patch \ + file://0064-target-arc-rewrite-command-arc-jtag-set-core-reg-as-.patch \ + file://0065-target-arc-rewrite-command-arc-get-reg-field-as-COMM.patch \ + file://0066-target-arc-rewrite-command-arc-num-actionpoints-as-C.patch \ + file://0067-target-arc-fix-error-handling-in-command-arc-set-reg.patch \ + file://0068-helper-nvp-add-openocd-nvp-files.patch \ + file://0069-target-arc-rewrite-command-arc-add-reg-type-flags-as.patch \ + file://0070-target-arc-rewrite-command-arc-add-reg-type-struct-a.patch \ + file://0071-target-arc-rewrite-command-arc-add-reg-as-COMMAND_HA.patch \ + file://0072-flash-nor-stm32l4x-Add-revision-Z-for-STM32L552-562-.patch \ + file://0073-README-Remove-statement-about-libjaylink-Git-submodu.patch \ + file://0074-new-SPI-memory-devices-continuation-code-for-manufac.patch \ + file://0075-flash-nor-spi-add-25pe-10-20-40-80-16.patch \ + file://0076-helper-command-drop-last-LF-n-from-sequence-of-comma.patch \ + file://0077-jtag-drivers-cmsis_dap-run-queue-on-reaching-transac.patch \ + file://0078-tlc-interface-does-fix-source-of-raspberrypi-gpio-co.patch \ + file://0079-tcl-board-at91sam9g20-ek-remove-outdated-FIXME.patch \ + file://0080-TODO-remove-outdated-AT91SAM92xx-entry.patch \ + file://0081-drivers-libusb_helper-allow-external-use-of-jtag_lib.patch \ + file://0082-drivers-ftdi-prevent-misleading-error-msg-when-more-.patch \ + file://0083-flash-nor-at91samd-fix-RAM-size-for-SAMR34-35.patch \ + file://0084-flash-nor-at91samd-add-missing-SAMR34-35-part-number.patch \ + file://0085-doc-add-missing-FreeRTOS-symbol.patch \ + file://0086-target-image-zero-initialize-ELF-segments-up-to-p_me.patch \ + file://0087-target-xtensa-add-NX-support.patch \ + file://0088-helper-add-compiler.h-to-handle-compiler-specific-wo.patch \ + file://0089-openocd-drop-JIM_EMBEDDED-macro.patch \ + file://0090-build-fix-distcheck-for-jimtcl.patch \ + file://0091-jimtcl-update-to-version-0.82.patch \ + file://0092-tcl-tools-test_cpu_speed-Fix-register-name.patch \ + file://0093-tcl-remove-exec-permission-to-tcl-config-files.patch \ + file://0094-svf-new-command-line-options-noreset-and-addcycles.patch \ + file://0095-helper-compiler-fix-build-on-MacOS.patch \ + file://0096-rtos-nuttx-add-Espressif-target-support-and-refactor.patch \ + file://0097-target-espressif-check-common_magic-instead-of-gdb_a.patch \ + file://0098-target-adi_v5_swd-update-comment-about-SWD-capabilit.patch \ + file://0099-target-adi_v5_jtag-fix-endianness-error-in-transacti.patch \ + file://0100-svf-fix-leaking-file-descriptor.patch \ + file://0101-svf-fix-memory-leak-on-error-during-command-executio.patch \ + file://0102-svf-make-command-svf-syntax-consistent.patch \ + file://0103-helper-command-rewrite-command-ocd_find-as-COMMAND_H.patch \ + file://0104-transport-rewrite-command-transport-select-as-COMMAN.patch \ + file://0105-flash-nor-rewrite-command-flash-list-as-COMMAND_HAND.patch \ + file://0106-helper-util-rewrite-command-ms-as-COMMAND_HANDLER.patch \ + file://0107-openocd-rewrite-command-version-as-COMMAND_HANDLER.patch \ + file://0108-rtt-rewrite-command-rtt-channellist-as-COMMAND_HANDL.patch \ + file://0109-target-aarch64-rewrite-commands-aarch64-mcr-mrc-as-C.patch \ + file://0110-target-armv4_5-rewrite-commands-arm-mcr-mrc-as-COMMA.patch \ + file://0111-target-cti-rewrite-command-cti-names-as-COMMAND_HAND.patch \ + file://0112-jtag-rewrite-command-adapter-name-as-COMMAND_HANDLER.patch \ + file://0113-jtag-rewrite-command-jtag-names-as-COMMAND_HANDLER.patch \ + file://0114-jtag-rewrite-command-jtag-arp_init-as-COMMAND_HANDLE.patch \ + file://0115-jtag-rewrite-command-jtag-arp_init-reset-as-COMMAND_.patch \ + file://0116-jtag-rewrite-command-flush_count-as-COMMAND_HANDLER.patch \ + file://0117-target-arm_dap-rewrite-command-dap-names-as-COMMAND_.patch \ + file://0118-target-arm_tpiu_swo-rewrite-command-tpiu-disable-as-.patch \ + file://0119-target-arm_tpiu_swo-rewrite-command-tpiu-enable-as-C.patch \ + file://0120-target-arm_tpiu_swo-rewrite-command-tpiu-names-as-CO.patch \ + file://0121-target-arm_tpiu_swo-rewrite-command-tpiu-init-as-COM.patch \ + file://0122-target-rewrite-command-read_memory-as-COMMAND_HANDLE.patch \ + file://0123-target-rewrite-command-target-curstate-as-COMMAND_HA.patch \ + file://0124-target-rewrite-command-was_examined-as-COMMAND_HANDL.patch \ + file://0125-target-rewrite-command-examine_deferred-as-COMMAND_H.patch \ + file://0126-target-rewrite-command-arp_halt_gdb-as-COMMAND_HANDL.patch \ + file://0127-target-rewrite-command-target-current-as-COMMAND_HAN.patch \ + file://0128-target-rewrite-command-target-types-as-COMMAND_HANDL.patch \ + file://0129-target-rewrite-command-target-names-as-COMMAND_HANDL.patch \ + file://0130-target-rewrite-command-target-smp-as-COMMAND_HANDLER.patch \ + file://0131-tcl-board-calao-usb-a9260-fix-and-refactor-broken-su.patch \ + file://0132-tcl-board-add-Calao-USB-A9G20.patch \ + file://0133-flash-nor-missing-fileio_close.patch \ + file://0134-github-workflow-increase-delete-tag-and-release-vers.patch \ + file://0135-github-workflow-build-libjaylink-from-source.patch \ + file://0136-rtos-FreeRTOS-some-optimization-of-freertos_update_t.patch \ + file://0137-src-target-mips_m4k-fix-condition-on-overlapping-wor.patch \ + file://0138-src-target-mips_m4k-add-fast-read-method.patch \ + file://0139-helper-list-remove-unused-hlist_.patch \ + file://0140-helper-list-re-align-with-Linux-kernel-6.3-rc1.patch \ + file://0141-ipdbg-whitespaces.patch \ + file://0142-helper-compiler-fix-build-with-gcc-on-MacOS.patch \ + file://0143-tcl-zynq_7000-add-missing-id-codes.patch \ + file://0144-tcl-cpld-xilinx-xc7-remove-virtex-7-devices-with-ir-.patch \ + file://0145-doc-drop-resume-will-wait-5-seconds.patch \ + file://0146-target-espressif-add-application-tracing-functionali.patch \ + file://0147-src-server-Fix-memory-leak-of-reg_list.patch \ + file://0148-rtos-linux.c-Fix-Linux-user-space-border-check.patch \ + file://0149-flash-rsl10-fix-typo.patch \ + file://0150-pld-move-file-sanity-checks-to-pld.c.patch \ + file://0151-Committing-changes-from-do_patch.patch \ + " SRCREV_FORMAT = "openocd" SRCREV_openocd = "91bd4313444c5a949ce49d88ab487608df7d6c37" @@ -17,7 +168,7 @@ SRCREV_git2cl = "8373c9f74993e218a08819cbcdbab3f3564bbeba" SRCREV_jimtcl = "fcbb4499a6b46ef69e7a95da53e30796e20817f0" SRCREV_libjaylink = "9aa7a5957c07bb6e862fc1a6d3153d109c7407e4" -PV = "0.12+gitr${SRCPV}" +PV = "0.12.0" S = "${WORKDIR}/git" inherit pkgconfig autotools-brokensep gettext